티스토리 뷰

www.acmicpc.net/problem/1662

 

1662번: 압축

압축되지 않은 문자열 S가 주어졌을 때, 이 문자열중 어떤 부분 문자열은 K(Q)와 같이 압축 할 수 있다. K는 한자리 정수이고, Q는 0자리 이상의 문자열이다. 이 Q라는 문자열이 K번 반복된다는 뜻이

www.acmicpc.net

문제는 위에서 확인할 수 있으며 예제로 주어진 압축 문자의 압축을 푸는 방법을 보면 아래와 같습니다.

 

33(562(71(9)))

=> 33(562(79))

=> 33(567979)

=> 3567979567979567979

=> 결과: 19

 

처음에는 아주 쉽게 생각해서 순서대로 스택에 저장하다가 ")" 가 들어온 경우 "(" 를 찾을 때까지 앞으로 이동하면서 그 수를 세고 "(" 를 만나면 그 앞에 있는 수를 곱해서 다시 카운트에 넣는 방법을 사용하였습니다. 하지만 이 경우는 완벽하게 ((())) 형태로 있을 때만 가능한 경우이고 33(562(71(9)))44(2) 와 같이 ((()))() 식의 괄호가 들어오면 처리하지 못하는 문제가 있었습니다.

 

따라서 입력 값이 "(" 인 경우는 그냥 그대로 스택에 저장하고, ")" 인 경우는 앞으로 이동하면서 "(" 를 찾을 때까지 사이의 수(사이 문자열의 길이)를 더하고 "(" 괄호를 찾으면 그 앞에 있는 수와 사이의 수를 곱해서 다시 스택에 저장하였습니다.

그리고 문자가 들어오는 경우를 "숫자, (" 와 "숫자, 숫자" 인 경우로 나누어 "숫자, (" 인 경우는 해당 숫자가 반복 횟수이기 때문에 그대로 스택에 저장하고, "숫자, 숫자" 인 경우는 단순 문자열이기 때문에 문자열의 길이인 1을 저장하는 방식으로 문제를 해결하였습니다.

 

결과적으로 스택에 저장되는 순서대로 위 예제를 살펴보면 다음과 같습니다.

입력: 33(562(71(9)))

1 3 ( 1 1 2 ( 1 1 ( 1 => ) 가 들어오면 1 * 1

=> 1 3 ( 1 1 2 ( 1 1 => ) 가 들어오면 2 * (1 + 1)

=> 1 3 ( 1 1 4 => ) 가 들어오면 3 * (1 + 1 + 4) 

=>1 18

=> 결과: 1 + 18 = 19

 

파이썬 코드는 다음과 같습니다.

from sys import stdin

s = stdin.readline().strip()
stack = list()

for i in range(len(s)):
    if s[i] == "(":
        stack.append("(")
    elif s[i] == ")":  # 닫는 괄호가 들어오면
        cnt = 0
        while True:
            tmp = stack.pop()  # 다시 앞으로 돌아가면서
            if tmp == "(":     # 여는 괄호를 만날 때까지 반복
                break
            cnt += tmp         # () 사이에 저장된 문자열의 수를 더하기
        stack.append(int(stack.pop()) * cnt)  # "( 앞에 있는 반복 횟수 * () 사이 문자열의 크기" 를 구해서 다시 저장하기
    elif i < len(s) - 1 and s[i + 1] == "(":  # 숫자, ( 조합이 들어온 경우
        stack.append(int(s[i]))  # 숫자 그대로 반복 숫자로 추가
    else:  # 숫자, 숫자 조합이 들어온 경우
        stack.append(1)  # 숫자의 크기는 문자열 1개이므로 1을 저장

# 총 문자열의 길이 구하기
answer = 0
for st in stack:
    answer += st
print(answer)

 

자바 코드는 다음과 같습니다.

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        String[] strings = br.readLine().split("");
        List<Integer> stack = new ArrayList<>();

        for (int i = 0; i < strings.length; i++) {
            if (strings[i].equals("(")) {
                stack.add(-1);
            } else if (strings[i].equals(")")) {
                int cnt = 0;
                while (true) {
                    int tmp = stack.remove(stack.size() - 1);
                    if (tmp == -1) {
                        break;
                    }
                    cnt += tmp;
                }
                stack.add(stack.remove(stack.size() - 1) * cnt);
            } else if (i < strings.length - 1 && strings[i + 1].equals("(")) {
                stack.add(Integer.parseInt(strings[i]));
            } else {
                stack.add(1);
            }
        }

        int answer = 0;
        for (int s: stack) {
            answer += s;
        }

        System.out.println(answer);
    }
}
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함