전위, 중위, 후위 표기식에 대한 설명은 이 문서를 참고하자
중위 표기식을 후위 표기식으로 어떻게 변환하는지에 대해 잘 알아야만 간단하게 해결할 수 있는 문제이다. 원래는 중위 표기식의 연산자 우선순위에 따라 괄호를 친 후 연산자를 괄호 오른쪽으로 꺼내고 괄호만 지우는 방식으로 후위 표기식으로 바꾸는 방법이 가장 일반적이라고 하여 프로그램 알고리즘도 그러한 방향으로 구현하려 했으나, 1. 괄호를 추가하고, 2. 연산자를 옮기고,
3. 괄호를 지우는 방식이 번거롭고 코딩 분량도 많아져서 규칙을 찾아내서 간단하게 구현하고자 했다.
후위 표기식에서 중요한 점은 연산자 우선순위이다. 후위 표기식은 연산자의 우선순위에 따라 연산자의 위치가 변한다는 점을 꼭 인지해야한다.
연산자의 우선순위는 어떻게 결정될까?
1. 괄호 안에서부터 계산하는 것이 우선순위가 높다.
2. 앞에서부터 계산하는 것이 우선순위가 더 높다.
3. 같은 우선순에 있는 연산자들은 **앞에서부터 계산**한다.
문제의 예시를 보기로 들자면.
이를 스택으로 한번 생각해보자. 이 때 중요한 점은 기존 후기 표기식을 풀 때는 피연산자를 스택에 넣었던 것과는 반대로 중위 표기식을 후기 표기식으로 바꿀 때는 연산자를 스택에 유지해야한다. 한번 문제의 식을 예로 들어 스택으로 후기 표기식으로 바꿔보자.
즉,
위와 같은 과정으로 우리가 원하는 후기 표기식을 얻을 수 있다.
위 과정의 규칙은 크게 두가지를 적용시켰다.
위 두 가지 규칙을 적용시켜 중위 표기식을 한 바퀴 돌고나면 우리가 원하는 후기 표기식을 구할 수 있고 이를 코드로 구현하면 아래와 같다.
import sys
from collections import deque
input = sys.stdin.readline
s = input().strip()
q = deque()
ans = []
for c in s:
if c in ["+", "-", "*", "/", "(", ")"]:
if c == ")": #괄호가 닫히면 괄호안에 있는 연산들 모두 pop
while q[-1] != "(":
ans.append(q.pop())
q.pop()
elif c in ["*", "/"]:
#곱셈, 나눗셈 연산의 경우
#먼저 들어온 곱셈, 나눗셈이 우선순위 높으므로 앞에있는 곱셈, 나눗셈 연산자만 pop해준다.
while q and q[-1] in ["*", "/"]:
ans.append(q.pop())
q.append(c)
elif c in ["+", "-"]:
#덧셈, 뺼셈 연산의 경우
#먼저 들어온 모든 사칙연산자가 자신보다 우선순위가 높으므로 모든 사칙연산에 대해 pop해준다.
while q and q[-1] in ["+", "-", "*", "/"]:
ans.append(q.pop())
q.append(c)
else:
q.append(c)
else:
ans.append(c)
while q:
ans.append(q.pop())
print("".join(ans))