본문 바로가기
Baekjoon/[1] 자료구조

[백준] 9012번 괄호 JAVA (자바) 풀이

by Poorm 푸름 2023. 6. 20.

문제 9012번

 : 괄호 문자열은 두 개의 괄호 기호인 ‘(’ 와 ‘)’ 만으로 구성되어 있는 문자열
 : 괄호의 모양이 바르게 구성된 문자열을 올바른 괄호 문자열 =  VPS  [한 쌍의 괄호로 된 “( )” 문자열 = VPS]
   <예>  “(())()”  =  VPS   “(()(”  ≠  VPS
 : VPS 인지 아닌지를 판단해서 그 결과를 YES 와 NO 로 나타내기

 

 [입력]

 :  첫 번째 줄에는 입력 데이터의 수 T

    그 다음 줄은 괄호 문자열이 한 줄 (괄호 문자열의 길이는 2 이상 50 이하) 

 

 [출력]


  : VPS이면 YES, 아니면 NO (한 줄에 하나씩 차례대로 출력)

 

 [스택 연산]

 

  init()  스택을 초기화
  create()  스택을 생성
  is_empty(s)  스택이 비어있는지 검사
  is_full(s)  스택이 가득 찼는지 검사 
  push(e)  스택의 맨 위에 요소 e 추가
  pop(s)  스택의 맨 위 요소를 삭제
  peek(s)  스택의 맨 위 요소를 삭제하지 않고 반환
  top()  스택 맨 위에 있는 데이터 값 반환
  push()  스택에 데이터 삽입
  pop()  스택에서 데이터 삭제하여 반환
  isEmpty()  스택에 원소가 없으면 'True', 있으면 'False' 값 반환
  isFull()  스택에 원소가 없으면 'False', 있으면 'True' 값 반환

 

 [코드]

import java.io.*;
import java.util.*;
 public class Main{
     public static void main(String[] args)throws IOException{
           BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
           int n = Integer.parseInt(br.readLine());
           StringBuilder sb = new StringBuilder();
           while(n-->0) {
            Stack<Character> stack = new Stack<>();
            String s = br.readLine();
            boolean b = true;  //b가 true면 YES, false면 NO
            for (int j = 0; j < s.length(); j++) {
                if (s.charAt(j) == '(') { // '('면 스택에 push 
                    stack.push('(');
                } else {// ')'면 스택에서 pop
                    if (stack.isEmpty()) {
                        b = false;
                        break;
                    }
                    stack.pop();
                }
            }
            if (!stack.isEmpty()) b = false;
               //아까 바꿨으니까 다시 원래대로 바꿔놓기
            if (b) {
                sb.append("YES\n");
            } else {
                sb.append("NO\n");
            }
        }
        System.out.print(sb);
    }
}

 

 [해설]

 

:  int n = Integer.parseInt(br.readLine()); 는 입력 첫줄에 받아온 숫자

:  StringBuilder sb = new StringBuilder(); 기존의 문자에 다른 문자열를 합칠때 유용
           
:  Stack<Character> stack = new Stack<>(); 문자별로 스택에 넣고 빼기


:  String s = br.readLine(); 한줄을 입력 받는다 (괄호들)


:  boolean b = true; 는 b가 true면 YES, false면 NO


:  if (s.charAt(j) == '(') {

                                     stack.push('(');  

                                     }  는 입력받은 문자가 '(' 라면 스택에 넣어준다


:  else {  

             stack.pop();

             } 는 입력받은 문자가 ')'이면 스택에서 빼라는 말이다

 

** 핵심 포인트 **

 

이때 짚고 넘어가야할 것은 '(' 과  ')' 을 한쌍으로 생각해야 한다는 것이다   

서로 쌍을 이루면 출력은 yes, 쌍을 이루지 않으면 출력은 no다

그렇다면 스택에 '('이 입력되었을때 ')'을 만나 쌍을 이루면 지워지게끔 만든다

 -   (    입력   =>   스택에   ( 넣기 

 -   )    입력   =>   스택에서 넣었던   ( 빼기  

그렇게 해서 스택이 다 비워지면 쌍을 이뤄 다 나간 것이라 yes 출력

비워있지 않고 남아있으면 쌍을 이루지 못한 괄호가 있다는 뜻이라 no를 출력 한다

 

:  if (stack.isEmpty()) {

                                      b = false;  

                                      break;

                                     } 는 스택 비어있을 경우에 ')' 나오면 pop 해줄게 없기 때문에 false로 바꾼다 

 

** 핵심 포인트 **

 

단 예외는 있다 이미 스택이 비워진 상태에서 ')' 를 만나면 스택에서 뺄 게 없다

이럴경우 스택이 비워져있지만 yes출력이 아닌 no를 출력하려면 boolean b를 false로 만들어 임의로 변경

= 원래는 스택비어있음 true 즉 yes 출력 , 예외로 스택비었을때 ')' 입력받음 false로 변경 즉 no 출력

 

:  if (!stack.isEmpty()) b = false; 아까 임의로 빈스택을 false로 바꿨으니까 다시 기본값으로 원래대로 바꿔

                                                   ( 비어있지 않을 때가 false 로 )
                       

 

                                                         

이제 풀어보러 갈께요 :)

 

 

https://www.acmicpc.net/problem/9012

 

9012번: 괄호

괄호 문자열(Parenthesis String, PS)은 두 개의 괄호 기호인 ‘(’ 와 ‘)’ 만으로 구성되어 있는 문자열이다. 그 중에서 괄호의 모양이 바르게 구성된 문자열을 올바른 괄호 문자열(Valid PS, VPS)이라고

www.acmicpc.net

 

 

* 독학으로 익히는 코딩이라 틀린 것이 있을 수 있습니다. 오류가 있다면 댓글을 통해 알려주세요. 감사합니다. *