icp_prior = {'+': 1, '*':2, '(':3}
isp_prior = {'+': 1, '*':2, '(':0}
def before_calc(str):
new_str= ''
stack = []
top = -1
for tk in str:
if tk.isdigit():
new_str += tk
else:
# 여는 괄호 or 연산자가 stack[top]의 우선순위보다 넣는 부호가 우선순위가 높을 경우
if tk == '(' or (tk in '*+' and isp_prior[stack[top]] < icp_prior[tk]):
top += 1
stack.append(tk)
# 연산자인데 우선순위가 stack에 있는 우선순위보다 낮을 경우
elif tk in '*+' and isp_prior[stack[top]] >= icp_prior[tk]:
while isp_prior[stack[top]] >= icp_prior[tk]:
top -= 1
new_str += stack.pop()
# 필요할 만큼 연산자를 꺼냈으니, 현재 들고있는 연산자를 다시 stack에 넣기
top += 1
stack.append(tk)
# 닫는 연산자가 나왔을 때
elif tk == ')':
while stack[top] != '(':
top -= 1
new_str += stack.pop()
# 닫는 연산자는 stack추가하지 않아도 된다, 그리고 pop한 '(' 도 추가하진 않는다.
top -= 1 # 하지만 top은 하나 더 줄었음
stack.pop()
return new_str
def calc_str(input_str):
stack = []
top = -1
for tc in input_str:
if tc.isnumeric():
stack.append(int(tc))
top += 1
elif tc == '*':
b = stack.pop()
top -= 1
a = stack.pop()
stack.append(a * b)
elif tc == '+':
b = stack.pop()
top -= 1
a = stack.pop()
stack.append(a + b)
return stack[top]
T = 10
for tc in range(1,T+1):
N = int(input())
calc_arr = input()
print(f'#{tc} {calc_str(before_calc(calc_arr))}')
실수한 부분
# list out of range error 발생
elif tk == ')':
while stack.pop() == '(':
top -= 1
new_str += stack.pop()
# 닫는 연산자는 stack추가하지 않아도 된다, 그리고 pop한 '(' 도 추가하진 않는다.
top -= 1 # 하지만 top은 하나 더 줄었음
1. stack.pop() != '(' 를 하지 않아서 while문이 돌아가지 않았었음
2. stack.pop() 이 2번 이루어지기 때문에, 2개씩 stack에서 사라져 갔었음
elif tc == '*':
b = stack.pop()
top -= 1
a = stack.pop()
result = a * b
stack[top] = result
elif tc == '+':
b = stack.pop()
top -= 1
a = stack.pop()
result = a + b
stack[top] = result
pop을 하는 것이기 때문에 top을 쓰기보다는 두번 pop 하고 한번의 append를 하는 것이 IndexError을 발생하지 않게 한다.
'알고리즘 문제풀이' 카테고리의 다른 글
Swea D2_11878.forth (1) | 2024.02.14 |
---|---|
Swea D3_11879. 미로 Python (1) | 2024.02.14 |
백준 1032 명령 프롬프트 브론즈1 Python (0) | 2024.02.09 |
백준 1075. 나누기 브론즈2 Python (0) | 2024.02.09 |
백준 2566. 최대값 브론즈3 Python (0) | 2024.02.09 |