-
Postfix Calculator(후위 표기식 계산기) 구현Algorithm 2021. 1. 13. 22:42
postfix란 뭘까
수식의 종류에는 prefix, infix, postfix 세 가지가 존재한다
이것은 연산자가 피연산자들 사이에서 어느 위치에 존재하느냐에 따라 나뉜다
우리는 일상생활에서 99.999999% Infix 방식을 이용해서 표기한다.
하지만 Infix방식에는 문제점이 존재한다
5+4*3 이라는 수식이 존재할 때, '*' 연산자가 '+' 연산자보다 우선순위가 높기 때문에 해당 수식을 먼저 계산해줘야 한다
하지만 이것은 계산을 하는 사람이 모든 수식을 차례로 읽은 뒤, 연산 순서를 임의로 정해야 한다.
그렇기 때문에 순차적으로 입력을 받고 이를 해결하는 컴퓨터의 계산 방식과는 약간 다르다.
컴퓨터는 postfix 연산 방식을 선호한다.
위의 수식을 postfix로 전환하면, 5 4 3 * + 이다.
postfix의 연산 방식은
1️⃣ 수식을 한 글자씩 읽어나간다
2️⃣ 연산자를 만나면, 연산자 바로 앞의 피연산자 두 개를 가지고 연산을 진행한다.
따라서 "5 4 3 * +"는, 피연산자를 계속 pass하다가 '*'를 만나서 연산을 진행한 뒤 "5 12 +"가 되고
'+'을 만나서 결과적으로 17이 된다.
그렇기 때문에 계산하는 측에서 연산자의 우선 순위를 따질 필요 없이 순차적으로 계산하기만 하면 된당
이러한 postfix calculator는 스택을 이용해서 구현할 수 있다
수식을 왼쪽에서 오른쪽으로 순차적으로 읽어들이면서
1️⃣ 현재 글자가 피연산자면 해당 피연산자를 stack에 push
2️⃣ 현재 위치가 연산자이면
- stack에 쌓여 있는 피연산자 두 개를 pop
- 현재 연산자를 이용해 두 피연산자를 계산
- 계산한 결과값을 stack에 push
3️⃣ 수식을 쭉 스캔하면서 1과 2를 반복한 뒤, 스캔이 끝나고 최종적으로 stack에 남아있는 값이 수식의 답
위의 그림은 stack을 이용한 postfix calculator의 동작 예시이다.
후위 표기식의 계산 코드는 아래와 같다 (백준1935번 후위표기식- www.acmicpc.net/problem/1935)
#include <cstdio> #include <stack> using namespace std; stack<double> s; char c, str[101]; int n, num[27]; double a, b; int main() { scanf("%d ", &n); scanf("%s", str); for (int i = 0; i < n; i++) scanf("%d", &num[i]); for (int i = 0; str[i] != NULL; i++) { c = str[i]; if (c == '\n')break; if ((c >= 'A') && (c <= 'Z')) { s.push(num[c - 'A']); } else { a = s.top(); s.pop(); b = s.top(); s.pop(); switch (c) { case '+': s.push(a + b); break; case '*': s.push(a * b); break; case '-': s.push(b - a); break; case '/': s.push((double)b / a); break; } } } printf("%.2lf", s.top()); return 0; }
'Algorithm' 카테고리의 다른 글
그래프의 Vertex를 정렬하는 Topological Sort - Kahn's Algorithm (0) 2021.02.15 [운영체제] LRU(Least Recently Used Algorithm) Algorithm이란? Python 구현 (0) 2021.02.05 재귀 구현에서 Recursion과 Iteration의 차이점 (0) 2021.01.08 Quick Select를 O(n)에 구현 가능한 Median of Medians 알고리즘 (0) 2021.01.03 Array의 k번째 작은 element 찾기 - QuickSelect 알고리즘 (0) 2021.01.01