[Gold V] 괄호의 값 - 2504
성능 요약
메모리: 31120 KB, 시간: 36 ms
분류
자료 구조, 구현, 스택
제출 일자
2024년 11월 12일 02:22:50
문제 설명
4개의 기호 ‘(
’, ‘)
’, ‘[
’, ‘]
’를 이용해서 만들어지는 괄호열 중에서 올바른 괄호열이란 다음과 같이 정의된다.
- 한 쌍의 괄호로만 이루어진 ‘
()
’와 ‘[]
’는 올바른 괄호열이다. - 만일
X
가 올바른 괄호열이면 ‘(X)
’이나 ‘[X]
’도 모두 올바른 괄호열이 된다. X
와Y
모두 올바른 괄호열이라면 이들을 결합한XY
도 올바른 괄호열이 된다.
예를 들어 ‘(()[[]])
’나 ‘(())[][]
’ 는 올바른 괄호열이지만 ‘([)]
’ 나 ‘(()()[]
’ 은 모두 올바른 괄호열이 아니다. 우리는 어떤 올바른 괄호열 X
에 대하여 그 괄호열의 값(괄호값)을 아래와 같이 정의하고 값(X
)로 표시한다.
- ‘
()
’ 인 괄호열의 값은 2이다. - ‘
[]
’ 인 괄호열의 값은 3이다. - ‘
(X)
’ 의 괄호값은 2×값(X
) 으로 계산된다. - ‘
[X]
’ 의 괄호값은 3×값(X
) 으로 계산된다. - 올바른 괄호열
X
와Y
가 결합된XY
의 괄호값은 값(XY
)= 값(X
)+값(Y
) 로 계산된다.
예를 들어 ‘(()[[]])([])
’ 의 괄호값을 구해보자. ‘()[[]]
’ 의 괄호값이 2 + 3×3=11 이므로 ‘(()[[]])
’의 괄호값은 2×11=22 이다. 그리고 ‘([])
’의 값은 2×3=6 이므로 전체 괄호열의 값은 22 + 6 = 28 이다.
여러분이 풀어야 할 문제는 주어진 괄호열을 읽고 그 괄호값을 앞에서 정의한대로 계산하여 출력하는 것이다.
입력
첫째 줄에 괄호열을 나타내는 문자열(스트링)이 주어진다. 단 그 길이는 1 이상, 30 이하이다.
출력
첫째 줄에 그 괄호열의 값을 나타내는 정수를 출력한다. 만일 입력이 올바르지 못한 괄호열이면 반드시 0을 출력해야 한다.
problem solving
1. 무엇이 문제인가
첫째 줄에 괄호열을 나타내는 문자열(스트링)이 주어진다.
첫째 줄에 그 괄호열의 값을 나타내는 정수를 출력한다.
- ‘
()
’ 인 괄호열의 값은 2이다. - ‘
[]
’ 인 괄호열의 값은 3이다. - ‘
(X)
’ 의 괄호값은 2×값(X
) 으로 계산된다. - ‘
[X]
’ 의 괄호값은 3×값(X
) 으로 계산된다. - 올바른 괄호열
X
와Y
가 결합된XY
의 괄호값은 값(XY
)= 값(X
)+값(Y
) 로 계산된다.
- 괄호의 종류에 따라 값이 정해져있다.
- 입력된 괄호에 따라 올바른 출력 값을 보여주어야 한다.
2. 문제의 원인은 무엇인가?
- stack을 어떻게 사용할지 모르겠음.
- stack이 비어있다면 더하기를 하도록 해야함.
- (()[[]])([])에서 ()[[]]를 → 2+9 로 만들고 *2를 해야하는데, 단순히 stack이 비어있다고 해서 이를 해결할 수 없음. (( “)” → “(”만 남은 경우에도 +로 변환해야함. 그러면 “(” 의 개수가 홀수일 경우 +라고 해야할까?
- 단순히 스택이 비어있는 것만 확인해서는 올바른 연산이 불가능함.
3. 문제를 해결할 방법에는 어떤 것들이 있는가?
- stack이 계산된 숫자로 연속될 경우는 + 연산을 해주었음.
- stack.pop의 결과가 숫자인 경우 한번 더 pop( 과정 1의 결과로 연속된 숫자는 나타나지 않으며, * 연산의 경우 숫자 뒤의 값은 괄호형태의 문자가 존재함) 후 해당 * 연산(2 또는 3) 을 진행함.
- stack.pop의 결과가 문자인 경우에 닫힌 괄호인 경우 pop후 해당 값(2 또는 3)을 append
* 괄호 연산 과정이 끝난 후에도 괄호의 숫자의 짝이 맞지 않는 경우.
* 과정 2에서 한번 더 pop을 했을 경우 괄호의 짝이 맞지 않는 경우
4. 풀이
import sys
strs = sys.stdin.readline().rstrip()
global stack
stack = []
def stack_check(strs):
count1 = 0
count2 = 0
for i in strs:
if(i == "(" ) :
count1 += 1
if(i == "[" ) :
count2 += 1
if(i not in "()[]"):
return 0
# stack에 숫자가 연속되어 있는 경우 + 연산
if(stack and type(stack[-1])) == int :
tmp = []
while(stack and type(stack[-1])) == int:
check = stack.pop()
tmp.append(check)
if(tmp != []):
stack.append(sum(tmp))
if(i == ")" and stack):
count1 -= 1
pop_e = stack.pop()
# stack의 top이 숫자인 경우 곱셈 연산
if(type(pop_e)) == int:
if(stack != []):
m_c = stack.pop()
if(m_c != "("):
return 0
stack.append(pop_e * 2)
else:
stack.append(2)
elif(i == "]" and stack):
count2 -= 1
pop_e = stack.pop()
# stack의 top이 숫자인 경우 곱셈 연산
if(type(pop_e)) == int:
if(stack != []):
m_c = stack.pop()
if(m_c != "["):
return 0
stack.append(pop_e * 3)
else:
stack.append(3)
else:
stack.append(i)
# 괄호 연산 후에 짝이 맞지 않는 경우
if(count1 != 0 or count2 != 0):
return 0
for i in stack:
if(type(i)== str):
return 0
return sum(stack)
print(stack_check(strs))
코드를 작성하고 구글에서 모든 테스트 케이스를 찾아서 적용해도 통과하지만, 백준에서 통과하지 못하는 테스트 케이스가 있었다.
strs = sys.stdin.readline().rstrip()
이 rstrip()를 추가하니 통과할 수 있었다.
if(i not in "()[]"):
return 0
이 조건을 통해서 충분히 처리를 했다고 생각했다. 공백이 들어가면 return 0이 나오는게 더 상식적인 것 같은데도 불구하고 테스트 케이스를 통과하려면 입력의 공백을 제거해야한다. 이것 때문에 시간이 더 오래걸려서 아쉬웠다. 쥐엔장!!!