파게로그

[백준 1662번] 압축 본문

콤퓨타 왕왕기초/PS

[백준 1662번] 압축

파게 2020. 11. 24. 06:21

문제 링크: 1662번 압축

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

 

s[i]s[i+1]이 '('가 아닌 다른 문자이면 일반 문자열이므로 length에 1을 더해준다. s[i+1]이 '('이면 괄호 안에 오는 문자열이 반복되는 횟수를 나타내므로, 이는 괄호 안의 문자열의 길이와 곱해져야 한다. 괄호 안의 문자열에 대해서 unzip()을 호출해주고, 다음으로 처리해야 할 문자의 인덱스, 즉 i를 괄호 다음으로 넘겨서 계속 읽어나간다. 이렇게 하면 여러 개의 괄호가 있는 경우, 그리고 괄호 뒤에 또 다른 문자열이 나오는 경우도 처리할 수 있다.

오히려 문제는 '괄호 안의 문자열'이 어디부터 어디까지를 말하는 것인가에 있었다. 스택이 빌 때까지 오른쪽 괄호를 찾아 나서면, 스택이 비게 되는 지점이 왼쪽 괄호와 쌍이 맞는 괄호가 있는 지점이다. 다만 이렇게 하면 안쪽 괄호에 대해서는 또다시 동일한 과정을 수행하므로 O(N^2)이 될 것인데, 한 번에 모든 괄호의 쌍을 찾을 방법은 없을지 고민해봐야겠다.

 

Python

def unzip(s):
    if len(s) == 0: return 0

    length = 0
    stack = 0

    i = 0 # s에서 현재 인덱스
    while i < len(s) - 1:
        ### 다음 문자가 '('가 아닌 다른 문자가 온다면 s[i]는 일반 문자이다.
        if s[i+1] != '(':
            length += 1
            i += 1
            continue

        ### 다음 문자가 '('가 온다면 s[i]는 반복 횟수이다.
        coef = int(s[i]) # 반복 횟수

        stack += 1
        idx = i+1 # 왼쪽 괄호 다음 인덱스부터 시작해서 stack이 빌 때까지 오른쪽 괄호를 찾는다.
        while stack > 0:
            idx += 1
            if s[idx] == '(': stack += 1
            if s[idx] == ')': stack -= 1
        # while문을 벗어나면 idx는 닫는 괄호를 가리킨다.

        midLength = unzip(s[i+2:idx]) # 괄호 안의 문자열에 대해 unzip()을 호출한다.
        length += coef*midLength

        i = idx + 1 # 괄호 다음으로 건너뛴다.

    if s[-1] != ')': length+=1

    return length

s = input()
print(unzip(s))

 

Java

import java.util.Scanner;

public class Main {
    static int unzip(String s) {
        if (s.length() == 0) return 0;

        int length = 0;
        int paren = 0;

        int i = 0;
        while (i < s.length() - 1) {
            if (s.charAt(i+1) != '(') {
                length++;
                i++;
                continue;
            }

            int coef = (int)(s.charAt(i) - '0');

            paren++;
            int idx = i+1;
            while (paren > 0) {
                idx++;
                if (s.charAt(idx) == '(') paren++;
                if (s.charAt(idx) == ')') paren--;
            }

            int midLength = unzip(s.substring(i+2, idx));
            length += coef * midLength;

            i = idx + 1;
        }

        if (s.charAt(s.length() - 1) != ')') length++;

        return length;
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String s = sc.next();
        sc.close();
        System.out.println(unzip(s));
    }
}
Comments