Published 2023. 3. 6. 20:45

들어가며

  • VPS는 기본 문자열 쌍으로 괄호가 올바르게 배치되어 있는가를 확인하는 문제이다.
  • 이때 올바르게 배치되었다 라는 상태의 정의는 괄호의 ( 과 ) 가 쌍을 이룰 수 있도록 배치되어 있는 상태를 말한다.
    • 예시를 들어 (())라는 괄호 쌍은 올바르게 배치되었다. ( 와 )가 쌍을 잘 이루고 있기 때문이다.
    • 다른 예시로 (())((는 올바르지 않은 배치이다. 뒤의 ((의 쌍이 존재하지 않기 때문이다.
    • 다른 예시로 )(는 올바르지 않은 배치이다. 닫힌 괄호가 먼저 나와있기 때문이다.
  • String 배열로 문자열들이 들어온다. 문자열들은 모두 ( 또는 )로 이루어져 있으며 다른 입력이 들어오는 경우는 존재하지 않는다. 이때 각 문자열들이 VPS로 올바르게 배치되었는지 확인하여 그 결과를 배열로 반환하는 함수를 구현하는것이 문제이다.
import java.util.*;

public class UserSolution {
    public static void main(String[] args){
        String[] dataSet = {"()()(())(((()))())", "()", ")(", "((())()()))((())()(())", "(())(())()()"};
        boolean[] result = solution(dataSet);

        for (boolean element: result){
            System.out.println(element);
        }
    }

    static boolean[] solution(String[] dataSet){
        
    }
}

 

 

접근 방법

  • 단순하게 생각하여 접근하면 닫힌 괄호가 입력으로 들어올 때 이전에 돌아봤던 괄호들 중 쌍이 되지 않고 열린 괄호가 있는지를 찾으면 된다.
    • 해당 방법은 잘 들어맞는것 처럼 보인다. 하지만 이전에 탐색했던 모든 문자열들을 다시 살펴봐야 하기 때문에 해당 방법은 길이가 길어지면 사용하기 힘든 방법이 된다.
  • 그렇다면 스택을 사용하는 방법을 생각해보자. 그럼 스택을 어떻게 사용해야 할까
    • VPS의 기본적인 성립 조건은 쌍이 모두 이루어질 수 있는가이다. 따라서 열린 괄호를 스택에 넣고, 닫힌 괄호가 입력으로 들어올 시 스택을 검사하여 열린 괄호가 존재한다면 이 두 괄호는 쌍이 될 수 있다는 것이다.
    • 쌍이 완성되는 괄호이기 때문에 더 이상 검사할 필요가 없다. 따라서 스택에서 해당 열린 괄호를 제거한다.
    • 만약 문자열이 모두 끝났다면 그 시점에서 스택에 괄호가 남겨져 있을 시 열린 괄호에 쌍이 될 닫힌 괄호가 존재하지 않는다는 것이므로 해당 문자열은 VPS가 아니다.
    • 문자열이 모두 끝난 시점에서 괄호가 남겨져 있지 않다면 모든 열린 괄호에 쌍이 될 닫힌 괄호가 존재한다는 것이므로 VPS이다.
  • 위 로직을 짠 코드는 아래와 같다.
import java.util.*;

public class UserSolution {
    public static void main(String[] args){
        String[] dataSet = {"()()(())(((()))())", "()", ")(", "((())()()))((())()(())", "(())(())()()"};
        boolean[] result = solution(dataSet);

        for (boolean element: result){
            System.out.println(element);
        }
    }

    static boolean[] solution(String[] dataSet){
        boolean[] result = new boolean[dataSet.length];

        for (int i = 0; i < dataSet.length; i++){
            Deque<Character> stack = new ArrayDeque<>();
            boolean res = true;

            for (int j = 0; j < dataSet[i].length(); j++){
                if (dataSet[i].charAt(j) == ')'){
                    if (stack.isEmpty()){
                        res = false;
                        break;
                    } else{
                        if (stack.peekLast() == '('){
                            stack.pollLast();
                        } else{
                            res = false;
                            break;
                        }
                    }
                } else{
                    stack.addLast(dataSet[i].charAt(j));
                }
            }

            res = res && stack.isEmpty();
            result[i] = res;
        }

        return result;
    }
}
  • 각 문자열을 탐색하며 열린 괄호인지 닫힌 괄호인지를 확인하고 그에 맞는 연산을 수행한다.
  • 위에서 설명한 괄호쌍이 맞지 않는 경우가 나온다면 VPS가 아니기 때문에 false를 배열에 넣고, 모든 조건을 통과하여 VPS라는 것이 증명되면 true를 배열에 넣는다.

 

'DataStructure > List' 카테고리의 다른 글

Stack의 활용 - Programmers 같은 숫자는 싫어  (0) 2023.03.13
Stack의 활용 문제 - BOJ 25556번 포스택  (0) 2023.03.13
덱(deque)의 정의와 구현  (0) 2023.02.23
큐(Queue)의 정의와 구현  (0) 2023.02.23
Stack의 구현  (0) 2023.02.20
복사했습니다!