https://www.acmicpc.net/problem/1662
1662번: 압축
압축되지 않은 문자열 S가 주어졌을 때, 이 문자열중 어떤 부분 문자열은 K(Q)와 같이 압축 할 수 있다. K는 한자리 정수이고, Q는 0자리 이상의 문자열이다. 이 Q라는 문자열이 K번 반복된다는 뜻이
www.acmicpc.net
문제 상황
K를 한자리 정수라고하고, Q를 0자리 이상의 문자열이라고 합니다.
K(Q)는 Q의 문자열이 K개가 중복된 것을 의미합니다.
예를 들어 12(34) 라면, 이 문자는 13434를 의미하는 것입니다.
이렇게 압축되어 있는 문자열을 풀어서, 문자열의 길이를 구하는 문제입니다.
풀이 방법
재귀에 속하는 문제이므로 재귀를 사용하려 했으나, 다음과 같이 문자열을 모두 저장하였더니 메모리 초과가 났습니다.
- 문자열을 받아서, 반복문으로 문자를 하나씩 확인합니다.
- 숫자이면 스택에 저장합니다.
- 괄호가 열리면, 스택에 가장 마지막에 있는 문자 k 을 가져옵니다.
그리고 괄호 뒤에 있는 문자열부터 함수에 집어넣어서 괄호 안에 있는 문자열 subString을 가져옵니다.
스택에 N * subString 의 문자열을 넣습니다. - 괄호가 닫히면, 스택에 있는 문자열을 return 해줍니다.
이미 봤던 문자열을 처리하는 방법에서는 재귀함수 안의 반복문에서 사용하는 index를 넘겨주는 방식을 사용했습니다.
import sys
from collections import deque
def PressNumber(string):
stack = deque([])
i = 0
while i < len(string):
if string[i]=='(':
k = stack.pop()
num, subString = PressNumber(string[i+1:])
subInt = list(int(k)* subString)
stack += subInt
i += num
i+=1
elif string[i] == ')':
subString = ''.join(stack).strip()
return i+1, subString
else:
stack.append(string[i])
i += 1
return 0, ''.join(stack)
input = sys.stdin.readline
num, string = PressNumber(input().strip())
print(len(string.strip()))
그래서 재귀를 사용하면서, 위에 처럼 문자 자체를 저장하지 않고 문자열의 길이를 반환하는 재귀를 만들었습니다.
또한, 이미 봤던 문자열에 대해서는 전역변수처럼 배열을 사용하여 처리해 주었더니, 간단한 코드가 되었습니다.
import sys
check = [False] * 50
def PressNumber(idx):
temp = ''
count = 0
for i in range(idx,len(string)):
s = string[i]
if(check[i]):
continue
check[i] = True
if(s.isdigit()):
temp = s
count += 1
elif(s == '('):
subString = string[i+1:]
subCount = PressNumber(idx+1)
count = count - 1 + int(temp) * subCount
else:
return count
return count
input = sys.stdin.readline
string = input().strip()
print(PressNumber(0))
다음은 재귀를 사용하지 않고, stack 을 사용하여 만들었습니다.
import sys
from collections import deque
input = sys.stdin.readline
count = 0
temp = ''
string = input().strip()
stack = deque([])
for i in range(len(string)):
s = string[i]
if s.isdigit():
count += 1
temp = s
elif s == '(':
stack.append((temp, count-1))
count = 0
else:
num, beforeString = stack.pop()
count = int(num) * count + beforeString
print(count)
'알고리즘 공부' 카테고리의 다른 글
[백준/백트래킹] 2239번: 스도쿠 (0) | 2022.11.27 |
---|---|
[백준/정렬] 11000번 강의실 배정 (0) | 2022.08.28 |
[백준/그리디] 2212번 센서 (0) | 2022.08.21 |
[백준/DP] 2294번: 동전 2 (0) | 2022.08.14 |
[백준/정렬, 투 포인터] 2473번 세 용액 (0) | 2022.08.07 |