백준 - 9012

아따맘마·2021년 1월 15일
0

알고리즘 - 백준

목록 보기
41/53

문제

괄호 문자열(Parenthesis String, PS)은 두 개의 괄호 기호인 ‘(’ 와 ‘)’ 만으로 구성되어 있는 문자열이다. 그 중에서 괄호의 모양이 바르게 구성된 문자열을 올바른 괄호 문자열(Valid PS, VPS)이라고 부른다. 한 쌍의 괄호 기호로 된 “( )” 문자열은 기본 VPS 이라고 부른다. 만일 x 가 VPS 라면 이것을 하나의 괄호에 넣은 새로운 문자열 “(x)”도 VPS 가 된다. 그리고 두 VPS x 와 y를 접합(concatenation)시킨 새로운 문자열 xy도 VPS 가 된다. 예를 들어 “(())()”와 “((()))” 는 VPS 이지만 “(()(”, “(())()))” , 그리고 “(()” 는 모두 VPS 가 아닌 문자열이다.

여러분은 입력으로 주어진 괄호 문자열이 VPS 인지 아닌지를 판단해서 그 결과를 YES 와 NO 로 나타내어야 한다.

입력

입력 데이터는 표준 입력을 사용한다. 입력은 T개의 테스트 데이터로 주어진다. 입력의 첫 번째 줄에는 입력 데이터의 수를 나타내는 정수 T가 주어진다. 각 테스트 데이터의 첫째 줄에는 괄호 문자열이 한 줄에 주어진다. 하나의 괄호 문자열의 길이는 2 이상 50 이하이다.

출력

력은 표준 출력을 사용한다. 만일 입력 괄호 문자열이 올바른 괄호 문자열(VPS)이면 “YES”, 아니면 “NO”를 한 줄에 하나씩 차례대로 출력해야 한다.

풀이

맨처음엔 배열로 풀었다. ()의 개수가 짝이 맞으면 yes 아니면 no를 출력했는데 생각해보니
())(()의 경우 no가 출력이 되야 하는데 yes가 출력이 되서 문제가 발생했다.
그래서 처음엔 string을 erase해서 짝이 맞으면 지워 나가는 식으로 했는데 이상하게 맨 처음 문자만 지워지지가 않아 패스. (((()))의 경우 (만 남고 다 지워진다...)
그래서 마지막으로 생각한게 stack구조였다. 이 전문제가 stack 문제였어서 바로 생각이 났는데 이것도 처음엔 시행착오를 겪었다.

if (str[j] == '(')
	arr.push(str[j]);
else
{
	if (!arr.empty()){
		if (arr.top() == '(')
			arr.pop();
	}
	else
	{
		arr.push(str[j]);
		break;
	}	
}

이 조건에서 str[j] == )일 때

if (arr.top() == '(')
	arr.pop();
}
else
{
	arr.push(str[j]);
	break;
}	

이와 같이 top()이 (이면 없애주고 아니면 해당 문자를 넣어주고 반복문을 빠져나가는 식으로 했다. 이렇게 하니까 안되서 뭐가 문제지 했는데
구글링 해보니까 다음과 같은 주의사항이 있었다.

빈 스택에 대해선 top, pop 연산의 결과가 정의되어 있지 않아 오류가 발생하지 않는다. 오류가 발생되지 않더라도 프로그램이 중단될 가능성이 높다

만약 빈 스택인 상태에서 (를 만나면 top()을 반환하는데 빈 스택이니 프로그램이 중단된 듯 싶다. 그래서 empty()를 활용해서 먼저 스택이 비었는지 확인을 했다.

코드

#include <iostream>
#include <string>
#include <stack>
using namespace std;

int main()
{
    int n;
    string str;
    
	scanf("%d", &n);
	for (int i = 0 ; i < n ; i++){
		cin >> str;
		stack<char> arr;
		for (int j = 0 ; j < str.length() ; j++){
			if (str[j] == '(')
				arr.push(str[j]);
			else
			{
				if (!arr.empty()){
					if (arr.top() == '(')
						arr.pop();
				}
				else
				{
					arr.push(str[j]);
					break;
				}	
			}
		}
		if (arr.size() == 0)
			cout << "YES" << '\n';
		else
			cout << "NO" << '\n';
    }
}
profile
늦게 출발했지만 꾸준히 달려서 도착지점에 무사히 도달하자

0개의 댓글

관련 채용 정보