백준 4949 균형잡힌 세상 [JAVA]

Ga0·2023년 6월 14일
0

baekjoon

목록 보기
72/137
post-custom-banner

문제 해석

  • 9012 ; 괄호 문제 POST의 연장선의 느낌이다.
  • 이 문제에서 입력받는 요소는 문자(알파벳), 공백, 소괄호("()"), 대괄호("[ ]"), 온점(".") 가 있다.
    1. 대괄호, 소괄호는 여는 괄호와 닫는 괄호가 모두 1:1 매칭이 되어야 한다.
    2. 온점의 경우는 문자열의 끝은 모두 온점이어야한다.
    1. 마지막 종료 조건은 온점 하나(".")가 들어온다.
  • 위와 같은 규칙을 모두 만족하면 yes, 만족하지 않으면 no를 출력하면 된다.

틀린 코드

import java.io.*;

public class Main {
    static int size = 0; //현재 인덱스가 어디까지 저장되었는지 (괄호)
    static char[] stack; //괄호 스택

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        while(true) {

            String str = br.readLine(); // 하나의 괄호 문자열

            if(str.equals(".")){ //str이 온점('.')인 경우 반복문 빠지기
                break;
            }

            // 테스트의 수만큼 찾는 인덱스용 변수를 초기화해야한다.
            size = 0;

            //배열 초기화와 동시에 크기 지정
            stack = new char[str.length()]; // 소괄호 스택

            //문자열의 크기만큼 구해야 한다.(문자열 -> 문지 배열로)
            for (int j = 0; j < str.length(); j++) {

                if (str.charAt(j) == '(' || str.charAt(j) == '[') { // '(' : push()를 쓰고
                    push(str.charAt(j)); //괄호 스택에 추가

                } else if(str.charAt(j) == ')'){ //소괄호 닫는 괄호 일경우
                    if(size == 0){ // 괄호 스택 사이즈가 0보다 작거나 같으면
                        //닫는 괄호가 많은 경우도 체크를 해줘야하기 때문에
                        //이 경우에도 닫는 괄호를 배열에 추가해야한다.
                        push(str.charAt(j));
                    }else{ //스택 사이즈가 0보다 크면 하나 빼면 된다.
                        pop(1);
                    }

                } else if(str.charAt(j) == ']') { //대괄호 닫는 괄호 일경우
                    if (size == 0) { // 괄호 스택 사이즈가 0보다 작거나 같으면
                        //닫는 괄호가 많은 경우도 체크를 해줘야하기 때문에
                        //이 경우에도 닫는 괄호를 배열에 추가해야한다.
                        push(str.charAt(j));
                    } else { //스택 사이즈가 0보다 크면 하나 빼면 된다.
                        pop(2);
                    }
                }
            }

            //모든 괄호를 검사 완료했다면
            //스택이 비어있다면 괄호(대/소)가 모두 쌍을 이룬다는 것이고,
            //마지막 인덱스가 '.'이면 문자열의 끝은 '.'이어야 한다는 규칙을 성립
            if (empty()) {
                bw.write("yes" + "\n");
            } else { //스택이 비어있지 않다면 괄호가 어느 하나 부족하다는 뜻이므로
                bw.write("no" + "\n");
            }
        }

        br.close();
        bw.flush();
        bw.close();
    }

    //push 명령어(문자열 크기만큼)
    static void push(char ch) {
        stack[size] = ch;
        size++;
    }

    //pop 명령어
    static void pop(int type){
        if (type == 1 && stack[size-1] == '(') { //type이 1이면 소괄호
            stack[size-1] = '\0' ; //전에 들어있는 괄호가 (일 경우만 삭제한다.
            size--; //삭제했으니 size를 줄인다.
        } else if (type == 2 && stack[size-1] == '['){ //type이 2이면 대괄호
            stack[size-1] = '\0' ; //전에 들어있는 괄호가 (일 경우만 삭제한다.
            size--;
        }
    }

    //empty 명령어
    static boolean empty(){
        if(size == 0){
            return true;
        }

        return false; //비어있지 않으면
    }
}

틀린 결과

  • 틀린 이유를 찾을 수가 없어서 맞은 코드 포스트를 참고해봤는데, 로직 자체는 다른 게 없는 것 같은데 아래의 코드는 맞고 내 코드는 틀린 이유를 아직 찾지 못해, 다른 분이 하신 코드를 이해하고 문제 풀이를 제출했다.

  • 코드 출처 : stanger's Lab ; 4949 군형잡힌 세상 의 방법 4 : BufferedReader + char 기본 배열 부분이다.

맞은 코드

import java.io.*;

public class Main {

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        String s;

        while (true) {

            s = br.readLine();

            if (s.equals(".")) { // 종료 조건문
                break;
            }

            bw.write(solution(s) + "\n");
        }

        br.close();
        bw.flush();
        bw.close();
    }

    public static String solution(String s) {

        char[] stack = new char[s.length()];	// 스택처럼 사용할 배열
        int size = 0;

        for (char val : s.toCharArray()) {

            // 여는 괄호일 경우 배열에 저장 후 size 1증가
            if (val == '(' || val == '[') {
                stack[size] = val;
                size++;
            }

            // 닫는 소괄호일경우
            else if (val == ')') {

                // 요소가 비어있거나 pop할 원소가 소괄호랑 매칭이 안되는 경우
                if (size == 0 || stack[size - 1] != '(') {
                    return "no";
                }
                else {
                    size--;
                }
            }

            // 닫는 소괄호일경우
            else if (val == ']') {

                // 요소가 비어있거나 pop할 원소가 소괄호랑 매칭이 안되는 경우
                if (size == 0 || stack[size - 1] != '[') {
                    return "no";
                }
                else {
                    size--;
                }
            }
        }

        if (size != 0) {
            return "no";
        }
        else {
            return "yes";
        }
    }
}

맞은 코드의 결과

느낀 점

  • 틀렸다 이유를 모르겠다. 알고싶다.
post-custom-banner

0개의 댓글