BOJ 1918번 후위 표기식
전위, 중위, 후위 표기식
Prefix, Infix, Postfix Expression
일반적인 수식은 피연산자와 피연산자 사이에 연산자를 위치시킨다. A와 B를 더하는(+)연산을 기술할 때 A+B로 표현하듯이 말이다. 연산자를 피연산자들의 앞에 위치시키거나 뒤에 위치시키는 표기 방법을 각각 전위 Prefix, 후위 Postfix 표기식이라고 하며, 앞의 예시는 각각+AB, AB+로 쓸 수 있다.
중위 표기식에서 후위 표기식으로의 변환
피연산자는 그 상대적인 위치가 바뀌지 않으므로, 연산자만 위치를 바꿔서 넣어주면 된다. 그러기 위해 연산자를 담아놓는 스택을 하나 만들어서, 입력된 연산자를 추가하거나 제거하면서 진행한다.
- 입력된 수식을 문자열로 저장하고, 출력용 문자열을 빈 문자열로 초기화한다. 연산자를 담기 위한 opstack을 초기화한다.
- 입력 문자열을 앞에서부터 하나의 문자씩 접근한다.
- 문자가 피연산자인 경우, 출력용 문자열에 추가한다.
- 문자가 왼쪽 괄호 ‘(‘인 경우, opstack에 push한다.
- 문자가 오른쪽 괄호 ‘)’인 경우, 대응하는 왼쪽 괄호 ’(‘가 나올 때 까지 opstack에서 연산자를 pop하고 문자열에 추가한다.
- 문자가 연산자인 경우, opstack에 push한다. 그 전에, 이미 opstack에 있는 연산자들 중 우선순위가 높거나 같은 것들을 모두 pop한 후 문자열에 추가한다.
- 입력 문자열을 모두 읽었다면 opstack에 남아있는 연산자를 차례대로 pop하고 문자열에 추가한다.
처음 문제를 접근했을 때는 어떤 경우에 연산자를 하나 pop하거나 여러개를 pop해야 하는지 기준을 생각하지 못했었는데, 위의 과정 중 2-4에 그 답이 있다. 연산자의 우선순위를 딕셔너리 형식으로 저장해서, 곱셈과 나눗셈을 먼저 끝낼 수 있도록 했다.
풀이
1 | eq = input().strip() |
추가) 후위 표기식의 연산
우리에게 친숙한 중위표기식은 연산하기 쉽지만, 후위 표기식으로 변환된 경우 직관적이지 않다. 이 때도 스택 자료구조를 사용한다.
앞에서부터 문자를 하나씩 접근해서 피연산자라면 스택에 push하고, 연산자라면 스택에서 두 개의 피연산자를 pop한 후 연산한 결과를 다시 push한다.
예를 들어, 4 5 6 * +
의 후위표기식이 있다고 하자. 스택에 담긴 데이터는 아래와 같은 순서로 변하면서 마지막에는 최종 결과값만 남아있게 된다.
4
+5
4 5
+6
4 5 6
+*
4 30
++
34
참고자료
Problem Solving with Algorithms and Data Structures using Python, Chapter 4.9.