1 /* calculate.cpp
2 * 问题描述:
3 * 输入一个只包含个位数字的简单四则运算表达式字符串,
4 * 计算该表达式的值
5 * 注:
6 * 1、表达式只含 +, -, *, / 四则运算符,不含括号
7 * 2、表达式数值只包含个位整数(0-9),且不会出现0作为除数的情况
8 * 3、要考虑加减乘除按通常四则运算规定的计算优先级
9 * 4、除法用整数除法,即仅保留除法运算结果的整数部分。
10 * 比如8/3=2。输入表达式保证无0作为除数情况发生
11 * 5、输入字符串一定是符合题意合法的表达式,
12 * 其中只包括数字字符和四则运算符字符,
13 * 除此之外不含其它任何字符,不会出现计算溢出情况
14 * 要求实现函数:int calculate(int len,char *expStr)
15 * 【输入】
16 * int len: 字符串长度;
17 * char *expStr: 表达式字符串;
18 * 【输出】无
19 * 【返回】
20 * 计算结果
21 * 示例
22 * 1)输入:char *expStr = “1+4*5-8/3”
23 * 函数返回:19
24 * 2)输入:char *expStr = “8/3*3”
25 * 函数返回:6
26 */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <stack>
32
33 //判断运算符的优先级函数
34 int Precede(char a, char b)
35 {
36 switch (a)
37 {
38 case '*':
39 case '/':
40 if ((b == '+') || (b == '-'))
41 {
42 return 1; //a的优先级高于b
43 }
44 else
45 {
46 return 0; //a的优先级等于b
47 }
48 case '+':
49 case '-':
50 if ((b == '*') || (b == '/'))
51 {
52 return -1; //a的优先级低于b
53 }
54 else
55 {
56 return 0;
57 }
58 default:
59 printf("运算符错误!\n");
60 break;
61 }
62 }
63
64 int Operate(int j, int k, char operater)
65 {
66 //int temp = 0;
67 switch (operater)
68 {
69 case '+':
70 return k + j;
71 //break;
72 case '-':
73 return k - j;
74 //break;
75 case '*':
76 return k * j;
77 //break;
78 case '/':
79 //temp = k / j;
80 return k / j;
81 //break;
82 default:
83 printf("运算错误!\n");
84 break;
85 }
86 }
87
88 int calculate(int len, char *expStr)
89 {
90 //表达式异常处理,注意len <= 0要加括号
91 if ((len <= 0 ) || (expStr == NULL))
92 {
93 printf("表达式为空!\n");
94 }
95
96 int i = 0, j = 0, k = 0;
97 std::stack<int> date;
98 std::stack<char> operate;
99
100 while (i < len)
101 {
102 if ((expStr[i] >= '0') && (expStr[i] <= '9'))
103 {
104 date.push(expStr[i] - '0');
105 i++;
106 }
107 else if ((expStr[i] == '+') || (expStr[i] == '-')
108 || expStr[i] == '*' || expStr[i] == '/')
109 {
110 if (operate.empty())
111 {
112 operate.push(expStr[i]);
113 i++;
114 }
115 else
116 {
117 //与栈顶运算符判断优先级
118 switch (Precede(expStr[i], operate.top()))
119 {
120 case 0:
121 case -1: //栈顶运算符优先级高
122 j = date.top();
123 date.pop();
124 k = date.top();
125 date.pop();
126 //date.push(Operate(j, k , expStr[i]));
127 date.push(Operate(j, k , operate.top()));
128 operate.pop();
129 //i++;
130 break;
131 //case 0:
132 case 1: //栈运算符顶优先级低
133 operate.push(expStr[i]);
134 i++;
135 break;
136 default:
137 printf("优先级判断错误!\n");
138 break;
139 }
140 }
141 }
142 else
143 {
144 printf("表达式无法识别!\n");
145 break;
146 }
147 }
148
149 while (!operate.empty())
150 {
151 j = date.top();
152 date.pop();
153 k = date.top();
154 date.pop();
155 date.push(Operate(j, k , operate.top()));
156 operate.pop();
157 }
158
159 return date.top();
160 }
161
162 int main()
163 {
164 int len = 0;
165 int i= 0, input_flag = 0;
166
167 //为了提高程序的鲁棒性,写了下面一段循环
168 //此处关键是flushall()的使用,如果不使用
169 //由于键盘输入缓存的存在使得程序陷入死循环
170 //关于flush()参见我的下一篇博客
171 while (!input_flag)
172 {
173 printf("请输入表达式的长度:");
174 input_flag = scanf("%d", &len);
175 if (!input_flag)
176 {
177 printf("输入有误,仅可输入数字!\n");
178 //flushall();
179 }
180 flushall();
181 }
182
183 char *expStr = (char *)malloc(len * sizeof(char));
184 input_flag = 0;
185 while (!input_flag)
186 {
187 printf("请输入表达式:");
188 for (i = 0; i < len; i++)
189 {
190 input_flag = scanf("%c", &expStr[i]);
191 //scanf("%c", &expStr[i]);
192 /*if ((i < len) && (expStr[i] == '\n'))
193 {
194 printf("长度不够,请重新输入:");
195 i = 0;
196 }*/
197 if (!input_flag)
198 {
199 printf("表达式输入有误!\n");
200 flushall();
201 break;
202 }
203 }
204 }
205
206 printf("表达式的计算结果为:%d\n", calculate(len, expStr));
207 return 0;
208 }
209
210 //#include <iostream>
211 //
212 //using namespace std;
213 //
214 //int calculate(int len, char *expStr)
215 //{
216 // //定义操作符栈
217 // struct
218 // {
219 // char opdate[200];
220 // int top;
221 // }opstack;
222 //
223 // //定义栈操作符
224 // opstack.top = -1;
225 // int i = 0; //遍历字符串的下标
226 // int t = 0; //当前后缀表达式的长度
227 // char ch = expStr[i];
228 // while (ch != '\0')
229 // {
230 // switch (ch)
231 // {
232 // case '+':
233 // case '-':
234 // while (opstack.top != -1)
235 // {
236 // expStr[t] = opstack.opdate[opstack.top];
237 // opstack.top--;
238 // t++;
239 // }
240 // opstack.top++;
241 // opstack.opdate[opstack.top] = ch;
242 // break;
243 // case '*':
244 // case '/':
245 // while (opstack.top != -1 &&
246 // (opstack.opdate[opstack.top] == '*' ||
247 // opstack.opdate[opstack.top] == '/'))
248 // {
249 // expStr[t] = opstack.opdate[opstack.top];
250 // opstack.top--;
251 // t++;
252 // }
253 // opstack.top++;
254 // opstack.opdate[opstack.top] = ch;
255 // break;
256 // default:
257 // expStr[t] = ch;
258 // t++;
259 // break;
260 // }
261 // i++;
262 // ch = expStr[i];
263 // }
264 //
265 // while (opstack.top != -1) //将栈中所有剩余的运算符出栈
266 // {
267 // expStr[t] = opstack.opdate[opstack.top];
268 // opstack.top--;
269 // t++;
270 // }
271 // expStr[t] = '\0';
272 //
273 // struct
274 // {
275 // int numeric[200];
276 // int top;
277 // }date;
278 // date.top = -1;
279 // i = 0;
280 // ch = expStr[i];
281 // while (ch != '\0')
282 // {
283 // if (ch >= '0' && ch <= '9')
284 // {
285 // date.top++;
286 // date.numeric[date.top] = ch - '0';
287 // }
288 // else if ('+' == ch)
289 // {
290 // int tmp = date.numeric[date.top - 1] +
291 // date.numeric[date.top];
292 // date.top--;
293 // date.numeric[date.top] = tmp;
294 // }
295 // else if ('-' == ch)
296 // {
297 // int tmp = date.numeric[date.top - 1] -
298 // date.numeric[date.top];
299 // date.top--;
300 // date.numeric[date.top] = tmp;
301 // }
302 // else if ('*' == ch)
303 // {
304 // int tmp = date.numeric[date.top - 1] *
305 // date.numeric[date.top];
306 // date.top--;
307 // date.numeric[date.top] = tmp;
308 // }
309 // else if ('/' == ch)
310 // {
311 // if (date.numeric[date.top] == 0)
312 // {
313 // printf("cannot be zero of the divide\n");
314 // exit(1);
315 // }
316 // int tmp = date.numeric[date.top - 1] /
317 // date.numeric[date.top];
318 // date.top--;
319 // date.numeric[date.top] = tmp;
320 // }
321 // i++;
322 // ch = expStr[i];
323 // }
324 // return date.numeric[date.top];
325 //}
326 //
327 //void main()
328 //{
329 // char expStr[] = "9/3*5";
330 // printf("%s\n", expStr);
331 // int result = calculate(strlen(expStr), expStr);
332 // printf("%d", result);
333 //}
334