괄호 문제는 곧 스택!! 프로그래머스에서 스택을 이용하는 괄호 문제를 몇 개 풀어봤기 때문에 쉽게 생각했지만 예외 케이스가 너무 많아서 쉽지 않았던 문제다.
우선 스택의 특징을 생각해서 문제에 접근한다.
입력 예시인 ( ( ) [ [ ] ] ) ( [ ] )을 스택 구조로 표현하면 다음과 같다.
1. ( ), [ ] 가 올바른 괄호쌍이 되면 스택에서 빠져나온다.
2. pop 하면서 ( )는 2, [ ]는 3의 값을 스택에 다시 삽입한다.
3-1. 만약 괄호 안에 숫자가 들어 있으면
그 값을 (N)은 N x 2, [N]은 N x 3한다.
3-2. 괄호 안에 숫자가 여러개 들어 있으면
숫자들을 더하고 3-1의 곱 연산을 한다.
4. 이 과정을 입력받는 괄호가 끝날 때까지 반복한다.
기본적인 스택의 사용은 이렇지만, 실제 문제에서 연산을 수행하는 방법과 예외 경우를 생각하는 것이 상당히 애를 먹었다. 런타임 에러가 상당히 많이 발생함ㅠㅠ🤣
- 여는 괄호 '(', '[' 는 스택에 저장한다.
- 닫는 괄호는 ')', ']' 경우로 나누어 생각한다.
💡 두 닫는 괄호의 차이점은
연산을 x 2 하느냐, x 3 하느냐의 차이고 논리는 동일하다.
- 각 경우에 스택의 최상단 원소(TOP)을 확인하여 처리한다.
💡 이 때, 스택의 원소가 없다면 최상단 원소를 확인하는 경우 Error가 발생한다.
if stack and stack[-1]~ 과 같이 인덱스 오류를 피하도록 코딩해야 한다.
- 3의 논리 과정에서 짝이 맞지 않는 괄호가 있으면 exit()한다.
또, 모든 과정을 수행했을 때, 스택에 괄호가 남아있는 경우도 exit()하여 0을 출력한다.
- 모든 과정을 수행하고 스택에 숫자만 있는 경우 스택에 남아있는 숫자 합이 답이다.
s = list(input())
stack = []
for i in s:
if i in ['(', '[']: # 여는 괄호는 전부 스택에 저장
stack.append(i)
elif i == ')': # 닫는 괄호가 ')'인 경우
tmp = 0
while True:
if not stack:
print(0)
exit()
if stack and stack[-1] == '(': # 올바른 괄호 짝짓기 성공
stack.pop()
if tmp == 0: # 연산이 진행중이던 게 없으면 그냥 2 ex. ()
stack.append(2)
else: # (()) 같은 케이스
stack.append(2 * tmp)
break
elif stack and stack[-1] == '[': # 올바르지 않은 괄호
print(0)
exit()
else:
tmp += int(stack.pop())
elif i == ']': # 닫는 괄호가 ']'인 경우
tmp = 0
while True:
if not stack:
print(0)
exit()
if stack and stack[-1] == '[':
stack.pop()
if tmp == 0:
stack.append(3)
else:
stack.append(3 * tmp)
break
elif stack and stack[-1] == '(':
print(0)
exit()
else:
tmp += int(stack.pop())
for i in stack:
if i in ['(', ')', '[', ']']: # 짝짓는 걸 끝마쳤는데 스택에 괄호가 남아있다면 올바르지 않은 괄호
print(0)
exit()
else:
print(sum(stack))