◈ 오류 정정 및 피드백 환영
1918번: 후위 표기식
첫째 줄에 중위 표기식이 주어진다. 단 이 수식의 피연산자는 알파벳 대문자로 이루어지며 수식에서 한 번씩만 등장한다. 그리고 -A+B와 같이 -가 가장 앞에 오거나 AB와 같이 *가 생략되는 등의
www.acmicpc.net
🔎문제 분석
연산자가 나오기 전까지는 입력 받은 피연산자를 어떻게 연산해야 할지 알 수 없다. 따라서 연산자를 어떤 곳에 넣어두었다가 특정 조건을 만족하면 다시 꺼내 연산해야 하며, 이를 위해 스택(Stack)으로 접근하면 된다.
피연산자가 나오면 바로 출력한다.
if i.isalpha():
res += i
연산자가 나오면 바로 판단하지 말고 우선 스택에 저장한다.
그리고 다음 연산자가 나왔을 때 다시 꺼내 연산이 가능한지를 살펴본 뒤 출력한다.
쉽게 생각하기 위해 괄호는 없다고 전제하고 다음을 비교해 보자.
Ex 1
A+B*C-D/E → ABC*+DE/-
Ex 2
A*B*C-D/E → AB*C*DE/-
2번째 연산자인 *가 나왔을 때 스택에 들어있던 연산자를 출력하는지 여부는 해당 연산자가 +인지 *인지에 달려있다.
+인 경우에는 출력하지 않았고 *인 경우는 출력했다. 이는 연산자의 우선순위가 *가 더 높기 때문이다. 즉, 스택에 여러 개의 연산자가 들어있을 때 어떤 연산자까지 꺼내야 할지를 결정하기 위해서는 우선순위를 고려해야 한다.
만약 * 또는 / 가 나와 스택에 저장된 연산자를 살펴보는데 + 또는 -만 들어있다면 꺼내서는 안 된다(Ex 1). * 또는 /의 우선순위가 더 높기 때문에 먼저 연산이 되어서는 안 되기 때문이다. 즉, 이 경우에는 * 또는 /만 꺼내야 한다.
if i in ["*","/"]:
while stack and stack[-1] in ["*","/"]:
res += stack.pop()
stack.append(i)
반대로 + 또는 -가 나왔다면 별 조건 없이 바로 스택에 있는 연산자를 꺼내도 된다. * 또는 /라면 우선순위가 더 높기에 상관없고, + 또는 -일지라도 앞서 나온 연산자부터 처리하는 것이 맞기 때문에 상관없기 때문이다.
이번에는 괄호를 넣어서 비교해 보자.
Ex 1
A*B+C*A*B+C+A*B+C → AB*CA*B*+C+AB*+C+
Ex 2
A*B+C*(A*B+C)+A*B+C → AB*CAB*C+*+AB*+C+
C와 A를 출력하고 *가 나왔을 때 스택에 들어있던 3번째 연산자인 *를 출력한 Ex 1과 달리 Ex 2에서는 출력하지 않았다. 그 이유는 바로 스택에 들어있던 (이다. 이로 인해 위에서 설정한 조건(* 또는 /만 꺼내야 한다)에 어긋나므로 스택에 있는 연산자 (를 꺼내고 *를 마저 꺼낼 수가 없다. *는 괄호 안의 연산보다 우선순위가 낮기 때문이다.
따라서 괄호 안의 연산임을 확인해야 한다. 즉, + 또는 -가 나왔을 때 이제 조건을 추가해야 한다.
if i in ["+","-"]:
while stack and stack[-1] != "(":
res += stack.pop()
그렇지 않으면 괄호 안의 연산이 끝나지 않았음에도 괄호 바깥의 연산자 *까지 출력할 위험이 있기 때문이다.
)는 괄호 안의 연산이 끝남을 알려주기 때문에 괄호 안에 남아있던 연산자를 모두 출력하면 된다.
if i==")":
while stack and stack[-1] != "(":
res += stack.pop()
stack.pop()
괄호 안의 연산이 끝났다면 남아있던 스택에 있는 연산자 *를 꺼내 미뤄두었던 연산을 하면 된다.
🤦♀️유의 사항
)는 괄호 위치를 판단하기 위한 연산자일 뿐 굳이 스택에 저장할 필요가 없다.
import sys
input = sys.stdin.readline
a = list(input())
stack = []
res = ''
for i in a:
if i.isalpha():
res += i
elif i in ["+","-","*","/","("]:
if i in ["+","-"]:
while stack and stack[-1] != "(":
res += stack.pop()
elif i in ["*","/"]:
while stack and stack[-1] in ["*","/"]:
res += stack.pop()
stack.append(i)
elif i==")":
while stack and stack[-1] != "(":
res += stack.pop()
stack.pop()
res += ''.join(stack[::-1])
print(res)
'Algorithm > Python' 카테고리의 다른 글
[Python] 프로그래머스 - [1차] 추석 트래픽(Greedy) (0) | 2022.03.04 |
---|---|
[Python] 백준 - 10799번 쇠막대기(Stack) (0) | 2022.03.03 |
[Python] 백준 - 2805번 나무 자르기(Binary Search) (0) | 2022.03.01 |
[Python] 백준 - 2110번 공유기 설치(Binary Search) (0) | 2022.02.28 |
[Python] 백준 - 2512번 예산(Binary Search) (0) | 2022.02.27 |
댓글