1// postfix_calc.c
2// μ€νμ μ΄μ©ν νμ νκΈ°λ²(Postfix) κ³μ°κΈ°
3// μ€μ: (3 + 4) * 5 β νμ: 3 4 + 5 *
4
5#include <stdio.h>
6#include <stdlib.h>
7#include <ctype.h>
8#include <string.h>
9#include <stdbool.h>
10
11#define MAX_SIZE 100
12
13// μ€μν μ€ν (κ³μ° κ²°κ³Όκ° μ€μμΌ μ μμ)
14typedef struct {
15 double data[MAX_SIZE];
16 int top;
17} Stack;
18
19// μ€ν μ΄κΈ°ν
20void stack_init(Stack *s) {
21 s->top = -1;
22}
23
24// λΉμ΄μλμ§ νμΈ
25bool stack_isEmpty(Stack *s) {
26 return s->top == -1;
27}
28
29// Push
30void stack_push(Stack *s, double v) {
31 if (s->top < MAX_SIZE - 1) {
32 s->data[++s->top] = v;
33 }
34}
35
36// Pop
37double stack_pop(Stack *s) {
38 if (!stack_isEmpty(s)) {
39 return s->data[s->top--];
40 }
41 return 0.0;
42}
43
44// Peek
45double stack_peek(Stack *s) {
46 if (!stack_isEmpty(s)) {
47 return s->data[s->top];
48 }
49 return 0.0;
50}
51
52// μ°μ°μμΈμ§ νμΈ
53bool isOperator(char c) {
54 return c == '+' || c == '-' || c == '*' || c == '/' || c == '%';
55}
56
57// μ°μ° μν
58double applyOperator(double a, double b, char op) {
59 switch (op) {
60 case '+': return a + b;
61 case '-': return a - b;
62 case '*': return a * b;
63 case '/':
64 if (b == 0) {
65 printf("μ€λ₯: 0μΌλ‘ λλ μ μμ΅λλ€!\n");
66 return 0;
67 }
68 return a / b;
69 case '%':
70 if (b == 0) {
71 printf("μ€λ₯: 0μΌλ‘ λλ μ μμ΅λλ€!\n");
72 return 0;
73 }
74 return (int)a % (int)b;
75 default:
76 printf("μ μ μλ μ°μ°μ: %c\n", op);
77 return 0;
78 }
79}
80
81// νμ νκΈ°λ² κ³μ°
82// 곡백μΌλ‘ ꡬλΆλ ν ν° νμ: "3 4 + 5 *"
83double evaluatePostfix(const char *expr) {
84 Stack s;
85 stack_init(&s);
86
87 // μ
λ ₯ λ¬Έμμ΄ λ³΅μ¬ (strtokμ΄ μλ³Έμ μμ νλ―λ‘)
88 char *str = strdup(expr);
89 char *token = strtok(str, " ");
90
91 printf("κ³μ° κ³Όμ :\n");
92
93 while (token) {
94 // μ«μμΈμ§ νμΈ (μμλ μ²λ¦¬)
95 if (isdigit(token[0]) || (token[0] == '-' && strlen(token) > 1)) {
96 double num = atof(token);
97 stack_push(&s, num);
98 printf(" μ«μ %gλ₯Ό μ€νμ push\n", num);
99 }
100 // μ°μ°μ
101 else if (isOperator(token[0]) && strlen(token) == 1) {
102 if (s.top < 1) {
103 printf("μ€λ₯: μ°μ°μ '%c'λ₯Ό μ μ©ν νΌμ°μ°μκ° λΆμ‘±ν©λλ€!\n", token[0]);
104 free(str);
105 return 0;
106 }
107
108 double b = stack_pop(&s);
109 double a = stack_pop(&s);
110 double result = applyOperator(a, b, token[0]);
111
112 printf(" μ°μ°: %g %c %g = %g\n", a, token[0], b, result);
113 stack_push(&s, result);
114 }
115 else {
116 printf("μ€λ₯: μλͺ»λ ν ν° '%s'\n", token);
117 free(str);
118 return 0;
119 }
120
121 token = strtok(NULL, " ");
122 }
123
124 free(str);
125
126 // μ€νμ μ νν νλμ κ²°κ³Όλ§ λ¨μμΌ ν¨
127 if (s.top != 0) {
128 printf("μ€λ₯: μλͺ»λ νκΈ°λ² (μ€νμ %dκ°μ κ°μ΄ λ¨μ)\n", s.top + 1);
129 return 0;
130 }
131
132 return stack_pop(&s);
133}
134
135// μ°μ°μ μ°μ μμ λ°ν
136int precedence(char op) {
137 if (op == '+' || op == '-') return 1;
138 if (op == '*' || op == '/' || op == '%') return 2;
139 return 0;
140}
141
142// μ€μ νκΈ°λ²μ νμ νκΈ°λ²μΌλ‘ λ³ν (μ¬ν)
143// κ°λ¨ν ꡬν: κ΄νΈμ μ°μ°μ μ°μ μμ μ²λ¦¬
144void infixToPostfix(const char *infix, char *postfix) {
145 Stack s;
146 stack_init(&s);
147 int j = 0;
148
149 for (int i = 0; infix[i]; i++) {
150 char c = infix[i];
151
152 // 곡백 무μ
153 if (c == ' ') continue;
154
155 // νΌμ°μ°μ (μ«μλ λ³μ)
156 if (isalnum(c)) {
157 postfix[j++] = c;
158 postfix[j++] = ' ';
159 }
160 // μ¬λ κ΄νΈ
161 else if (c == '(') {
162 stack_push(&s, c);
163 }
164 // λ«λ κ΄νΈ
165 else if (c == ')') {
166 while (!stack_isEmpty(&s) && (char)stack_peek(&s) != '(') {
167 postfix[j++] = (char)stack_pop(&s);
168 postfix[j++] = ' ';
169 }
170 stack_pop(&s); // '(' μ κ±°
171 }
172 // μ°μ°μ
173 else if (isOperator(c)) {
174 while (!stack_isEmpty(&s) &&
175 precedence((char)stack_peek(&s)) >= precedence(c)) {
176 postfix[j++] = (char)stack_pop(&s);
177 postfix[j++] = ' ';
178 }
179 stack_push(&s, c);
180 }
181 }
182
183 // μ€νμ λ¨μ μ°μ°μ λͺ¨λ μΆλ ₯
184 while (!stack_isEmpty(&s)) {
185 postfix[j++] = (char)stack_pop(&s);
186 postfix[j++] = ' ';
187 }
188
189 postfix[j] = '\0';
190}
191
192// ν
μ€νΈ μ½λ
193int main(void) {
194 printf("=== νμ νκΈ°λ² κ³μ°κΈ° ===\n\n");
195
196 // νμ νκΈ°λ² κ³μ° ν
μ€νΈ
197 const char *postfixExpressions[] = {
198 "3 4 +", // 3 + 4 = 7
199 "3 4 + 5 *", // (3 + 4) * 5 = 35
200 "10 2 / 3 +", // 10 / 2 + 3 = 8
201 "5 1 2 + 4 * + 3 -", // 5 + ((1 + 2) * 4) - 3 = 14
202 "15 7 1 1 + - / 3 * 2 1 1 + + -", // 볡μ‘ν μ
203 "8 2 /", // 8 / 2 = 4
204 "9 3 % 2 *" // (9 % 3) * 2 = 0
205 };
206
207 int n = sizeof(postfixExpressions) / sizeof(postfixExpressions[0]);
208
209 printf("[ νμ νκΈ°λ² κ³μ° ]\n");
210 for (int i = 0; i < n; i++) {
211 printf("\n%d. Expression: %s\n", i + 1, postfixExpressions[i]);
212 double result = evaluatePostfix(postfixExpressions[i]);
213 printf(" μ΅μ’
κ²°κ³Ό: %.2f\n", result);
214 }
215
216 // μ€μ β νμ λ³ν ν
μ€νΈ
217 printf("\n\n[ μ€μ νκΈ°λ² β νμ νκΈ°λ² λ³ν ]\n");
218
219 const char *infixExpressions[] = {
220 "(3 + 4) * 5",
221 "a + b * c",
222 "(a + b) * (c - d)",
223 "a + b - c",
224 "a * b + c / d"
225 };
226
227 int m = sizeof(infixExpressions) / sizeof(infixExpressions[0]);
228
229 for (int i = 0; i < m; i++) {
230 char postfix[MAX_SIZE];
231 infixToPostfix(infixExpressions[i], postfix);
232 printf("\nμ€μ: %s\n", infixExpressions[i]);
233 printf("νμ: %s\n", postfix);
234 }
235
236 // λνν κ³μ°κΈ°
237 printf("\n\n[ λνν νμ κ³μ°κΈ° ]\n");
238 printf("νμ νκΈ°λ²μΌλ‘ μμμ μ
λ ₯νμΈμ (μ: 3 4 +)\n");
239 printf("μ’
λ£νλ €λ©΄ 'q'λ₯Ό μ
λ ₯νμΈμ.\n\n");
240
241 char input[MAX_SIZE];
242 while (1) {
243 printf("> ");
244 if (!fgets(input, MAX_SIZE, stdin)) break;
245
246 // κ°ν λ¬Έμ μ κ±°
247 input[strcspn(input, "\n")] = 0;
248
249 if (strcmp(input, "q") == 0) break;
250
251 double result = evaluatePostfix(input);
252 printf("κ²°κ³Ό: %.2f\n\n", result);
253 }
254
255 printf("νλ‘κ·Έλ¨μ μ’
λ£ν©λλ€.\n");
256 return 0;
257}