본문 바로가기

알고리즘 문제풀이

Swea D4_1224.계산기3 Python

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을 발생하지 않게 한다.