[백준9012번] 괄호

2020. 1. 24. 14:09
반응형

문제

괄호 문자열(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

나의 풀이

원래는 스택에 왼쪽괄호를 넣어가며 오른쪽 괄호를 만날때마다 왼쪽 괄호를 하니씩 pop하는 방식도 있겠지만 필자는 구지 List를 만들어서 스택에 문자를 저장할 필요없이 왼쪽 괄호를 만날때마다 count를 해가며 오른쪽 괄호를 만나면 count를 1씩 감소시키는 방법을 생각해서 풀었다.


우선 BufferedReader를 사용해 한 줄씩 입력받은 괄호 문자열을 Char[]로 컨버전을 해서 while문을 사용하여 반복을 해서 왼쪽 괄호와 오른쪽 괄호를 검사했다. while문에 들어가기 전에 countLeft를 0으로 초기화해두고 isValid라는 boolean형 변수를 두어 반복을 할때마다 괄호 문자열이 Valid한지를 저장했으며 while문의 조건으로는 j가 문자열의 길이보다 작고 isValid가 true로 설정했다. isValid를 둠으로써 쓸데없이 반복하는 경우를 없앨 수 있으며 결과값을 출력하는데도 사용할 수 있다.


반복문의 과정은 j번 인덱스의 값이 '('이면 countLeft값을 1 증가 시킨다. 만약 ')'라면 두 경우를 생각해야한다. countLeft값이 0인지 아닌지인데 0이라면 왼쪽 괄호가 앞에서 이미 모두 짝이 이루어졌거나 없는 경우로 바로 Valid하지 못하다는 경우다. 0이 아니라면 왼쪽 괄호와 짝을 이루면서 countLeft값을 1 감소시키면 된다.


이렇게 while반복문이 모두 돌고나면 isValid가 true이면서 동시에 countLeft가 0일 경우만이 VPS(Valid PS)가 된다. 주의해야할 점은 countLeft가 0이 아니라면 "(()()"와 같이 짝이 맞지않는 왼쪽 괄호가 남는다는 의미이다.


스택의 pop이 가능한지의 여부를 생각하고 풀면되는 문제였다.


코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * 9012번 괄호
 */
public class Baekjoon9012 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        int t = Integer.parseInt(br.readLine());

        for (int i=0; i<t; i++) {
            int countLeft = 0;
            char[] ps = br.readLine().toCharArray();

            int j = 0;
            boolean isValid = true;
            while(j<ps.length && isValid) {
                if (ps[j] == '(') countLeft++;
                else {
                    if (countLeft == 0) isValid = false;
                    else countLeft--;
                }
                j++;
            }

            if (isValid && countLeft==0) System.out.println("YES");
            else System.out.println("NO");
        }
    }
}
반응형

'Programming > Algorithm' 카테고리의 다른 글

[백준1874번] 스택 수열  (0) 2020.01.25
[백준4949번] 균형잡힌 세상  (0) 2020.01.24
[백준10773번] 제로  (0) 2020.01.24
[백준10828번] 스택  (0) 2020.01.24
[백준1676번] 팩토리얼 0의 개수  (0) 2020.01.19

BELATED ARTICLES

more