중위표기식의 식을 입력 받아서 후위 표기식으로 바꾼 후

계산하는 스택 계산기입니다.


후위로 바꾸는 방법을 모르신다면 아래의 글을 참고해주세요

http://donggod.tistory.com/45


그리고 정석적인 방법이 아닙니다!!!

그냥 제가 생각나는데로 코딩했기 때문입니다...ㅠ_ㅠ....(근데 이게 정석일수도? 냐하하..)


문자열로 받은 식을

후위로 바꿉니다.

후위로 바꿀 때 숫자 뒤에는 항상 '$'을 붙였습니다. 문자열이기 때문에 숫자라는 구분을 넣어준 것입니다.


예를들어 1000 + 300

이면

1000300+가 될텐데 1000300인건지 아니면 1000 300 인것인지 구분하기 위함입니다.

그래서 1000$300$+가 됩니다.


후위를 스택으로 계산하는 방법은

후위식에서 AB+C+라는 식이 있으면


A와 B를 스택에 삽입하고 기호를 만나면 스택에서 가장 위의 값 두개를 팝하고 +연산을 한 후에

다시 스택에 넣습니다.

과정을 보여드리자면


스택 : A,B

기호 : +


그럼 A와 B를 꺼내서 (A+B)라는 값이 만들어집니다


이것을 다시 스택에 넣습니다.


스택 : (A+B)

기호 : 


또 스택에 C가들어오겠죠

스택 : (A+B),C

기호 : +


또 두개를 꺼내서 계산합니다


(A+B+C)라는 값이 만들어지곘죠


스택 : A+B+C

기호 :


완성됐습니다!


아래는 코드입니다.

궁금한 점은 댓글 주세요


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include <cstdio>
#include <iostream>
#include <utility>
#include <stack>
#include <string.h>
using namespace std;
 
 
//이전 자료구조 글을 참고하세요 [1918] 후위표기식
// http://donggod.tistory.com/45
//그 코드에서 바뀐 부분만 주석 달겠습니다.
void prefix(char *str, char *output) {
    stack<char> s;
    int oIdx = 0;
 
    for (int i = 0; i < strlen(str); i++) {
        //A~Z가 아닌 숫자로 바뀜
        //숫자일 때 까지 output에 넣고
        //마지막에 '$'를 삽입
        //ex) 1000+30 이면 1000$30$+
 
        if (str[i] >= '0' && str[i] <= '9') {
            int j;
            for (j = i; str[j] >= '0' && str[j] <= '9'; j++) {
                output[oIdx++= str[j];
            }
            output[oIdx++= '$';
            i = j - 1;
        }
        else {
            if (str[i] == '(') s.push(str[i]);
            else if (str[i] == ')') {
                while (s.top() != '(') {
                    output[oIdx++= s.top();
                    s.pop();
                }
                s.pop();
            }
            else if (str[i] == '*' || str[i] == '/') {
                while (!s.empty() && (s.top() == '*' || s.top() == '/')) {
                    output[oIdx++= s.top();
                    s.pop();
                }
                s.push(str[i]);
            }
            else {
                while (!s.empty() && s.top() != '(') {
                    output[oIdx++= s.top();
                    s.pop();
                }
                s.push(str[i]);
 
            }
        }
    }
 
    while (!s.empty()) {
        output[oIdx++= s.top();
        s.pop();
    }
    output[oIdx] = '\0';
}
 
//prefix로 바뀐 output, 인덱스를 포인터로 받음
//'$'를 만날 때 까지 10씩 곱해주며 숫자로 바꾼 후 리턴
int toInt(char *output, int* idx) {
    int ret = 0;
    for (; output[*idx] != '$'; (*idx)++) {
        ret *= 10;
        ret += output[*idx] - '0';
    }
    return ret;
}
 
int calcuration(char *output) {
    stack<int> s;
 
    for (int i = 0; i < strlen(output); i++) {
        if (output[i] >= '0' && output[i] <= '9') {
            int a = toInt(output, &i);//문자열을 숫자로 바꿈
            s.push(a);//스택에 삽입
        }
        else {
            int b = s.top();
            s.pop();
            int a = s.top();
            s.pop();
 
            switch (output[i]) {
            case '+':
                a += b;
                break;
            case '-':
                a -= b;
                break;
            case '/':
                a /= b;
                break;
            case '*':
                a *= b;
                break;
            }
            
            s.push(a);
        }
    }
 
    return s.top();
}
 
int main() {
    char str[10000];
    char output[10000];
 
    scanf("%s", str);
    prefix(str, output);
 
    printf("%d\n", calcuration(output));
 
    return 0;
}
cs


'CS기본지식 > 자료구조' 카테고리의 다른 글

[C언어] 우선순위 큐(Priority Queue)  (3) 2017.09.07
[2263] 트리의 순회  (1) 2017.08.27
[1918] 후위표기식  (2) 2017.06.13
이중 연결 리스트  (0) 2017.04.22
단순 연결 리스트  (0) 2017.04.22

+ Recent posts