Computer Science/자료구조

백준 1918번 후위표기식 - 파이썬

somm12 2022. 7. 19. 08:47

 

 

1918번: 후위 표기식

첫째 줄에 중위 표기식이 주어진다. 단 이 수식의 피연산자는 알파벳 대문자로 이루어지며 수식에서 한 번씩만 등장한다. 그리고 -A+B와 같이 -가 가장 앞에 오거나 AB와 같이 *가 생략되는 등의

www.acmicpc.net

이 문제는 stack의 LIFO 특징을 이용해서 중위 표기식을 후위 표기식으로 변환시키는 문제이다. 입력 받은 문자열을 하나씩 읽어들여 연산자들만 stack에 넣고 각 연산자들의 우선순위 규칙에 맞게 pop, append를 한다. 나머지 피연산자들은 최종적으로 답이 될 빈 문자열에 더해준다.

올 수 있는 모든 연산자: +, -, *, /, (, )

우선순위 설정:

priority = {"*": 1, '/':1, '+':0, '-':0,'(':-1}

나는 문제를 풀기 위해서 문자열을 읽어들일 때, 경우를 나누고 우선순위를 부여했다.

1. '(' 인 경우 : 여괄호는 우선순위가 높기 때문에 항상 append를 시켜준다. 하지만 여괄호 다음으로 오는 다른 연산자들은 항상 append되어야 한다. ex) (+) 우선순위가 높긴 하지만 그 안의 연산자를 담아야하기 때문에 우선순위를 낮게 잡았다.

2. ')': 닫는 괄호가 오면 여괄호를 만날 때까지 stack.pop을 해주어 정답이 될 문자열에 더해줌. ex) ans += stack.pop()

3. 나머지 연산자들: stack[-1]의 우선순위가 다음으로 올 연산자보다 크거나 같다면 pop! -> stack[-1]의 우선순위가 다음 연산자보다 작을 때 까지 pop

** while문에서 조건을 쓸 때 index out of range 에러가 날 수 있는 위험성을 체크해야한다.

while stack[-1] ,,,, 보다는 while stack: 안에 조건문을 하나 더쓰자.

 

내 코드

from collections import deque
arr = deque(list(input()))

ans = ""
priority = {"*": 1, '/':1, '+':0, '-':0,'(':-1}
stack = []

while arr:
    val = arr.popleft()
    if ord(val) >= 65:
        ans += val
    else:
        if stack:
            if val == '(':
                stack.append(val)
            elif val == ')':
                while stack[-1] != '(':
                    ans += stack.pop()
                stack.pop()
            else:
                while stack:
                    if priority[val] <= priority[stack[-1]]:
                        ans += stack.pop()
                    else:
                        break                
                stack.append(val)
        else:
            stack.append(val)

while stack:
    ans += stack.pop()
for val in ans:
    print(val,end='')