괄호 문자열(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”를 한 줄에 하나씩 차례대로 출력해야 한다.
예제 입력 1
6
(())())
(((()())()
(()())((()))
((()()(()))(((())))()
()()()()(()()())()
(()((())()(
예제 출력 1
NO
NO
YES
NO
YES
NO
예제 입력 2
3
((
))
())(()
예제 출력 2
NO
NO
NO
문제 풀이
이번 문제는 올바른 괄호로만 문자열이 이루어졌는지 확인하는 문제입니다.
전체 문자열을 읽으며 짝이 맞는지 아닌지를 체크하는 로직이 필요하며 위와 같이 "짝지어 폭파하기" 컨셉의 문제는 스택 자료구조로 접근하는 것을 생각해볼 필요가 있습니다.
스택 자료구조의 경우 FILO(First In Last Out)이므로, 가장 최근에 들어온 요소(top)와 다음에 들어오는 요소를 쉽게 비교할 수 있으며, 올바른 짝이 되는 경우 스택에서 top을 제거하고, 아닌 경우 스택에 요소를 추가해주는 방식으로 쉽게 풀이가 가능합니다.
즉, 위와 같은 로직으로 모든 문자열을 순회했을 때 스택에 값이 남아있다면 모든 괄호가 짝이 되지 못한 경우라고 판단할 수 있습니다.
코드
풀이 시간 : 5m 2s
#include <iostream>
#include <stack>
using namespace std;
int n;
int main()
{
cin >> n;
for (int i = 0; i < n; i++)
{
string tempStr;
cin >> tempStr;
stack<char> stk;
for (int i = 0; i < tempStr.length(); i++)
{
// 스택이 비어있지 않다면?
if (!stk.empty())
{
// 맨 위의 값과 현재 값이 올바른 짝인지 비교
if (stk.top() == '(' && tempStr[i] == ')')
{
// 올바른 경우이므로 스택에서 해당 값 제거
stk.pop();
}
else
{
// 올바르지 않은 경우이므로 스택에 해당 값 추가
stk.push(tempStr[i]);
}
}
else
{
// 스택에 값 추가
stk.push(tempStr[i]);
}
}
// 결과 출력
if (stk.empty())
cout << "YES" << '\n';
else
cout << "NO" << '\n';
}
}
'코딩테스트 > 백준 (Study)' 카테고리의 다른 글
[백준 / C++] 222-풀링 (실버2, 17829) (0) | 2024.09.02 |
---|---|
[백준 / C++] 영역 구하기 (실버1, 2583) (0) | 2024.09.02 |
[백준 / C++] 쿼드트리 (실버1, 1992) (0) | 2024.09.02 |
[백준 / C++] 편의점 2 (실버2, 14400) (0) | 2024.09.01 |
[백준 / C++] 잃어버린 괄호 (실버2, 1541) (0) | 2024.08.31 |