1 //表达式求值 数据结构严蔚敏 表达式求值 代码实现
2 #include<iostream>
3
4 using namespace std;
5
6 typedef struct _NODE_
7 {
8 int a;
9 _NODE_* pNext;
10 }Node,*pNode;
11
12
13 int Precede(int cur,int sta); //优先级判断 函数
14
15 int EvaluateExpression(); //表达式求值 函数
16
17 int Result(int i,int Opr,int j); //结果计算 函数
18
19 bool IsOper(int a); //运算符判读 函数
20
21
22 class CStack //标准链性栈 类
23 {
24 private:
25 pNode m_pHead;
26 int m_iNodeCount;
27
28
29 public:
30 CStack()
31 {
32 m_pHead = NULL;
33 m_iNodeCount = 0;
34 }
35 ~CStack()
36 {
37
38 }
39
40 void InitStack();
41
42 bool IsEmpty();
43
44 bool PushStack(int a);
45
46 bool PopStack(int& a);
47
48 int GetTop();
49
50 int GetLength();
51
52 void DestroyStack();
53 };
54
55 int main()
56 {
57
58 cout<<EvaluateExpression()<<endl;
59
60
61
62 return 0;
63 }
64
65
66
67 void CStack::InitStack()
68 {
69 if(!IsEmpty())
70 {
71 DestroyStack();
72 }
73 m_iNodeCount = 0;
74
75 m_pHead = NULL;
76
77 }
78
79
80
81 bool CStack::IsEmpty()
82 {
83 if(m_iNodeCount == 0)
84 {
85 return true;
86 }
87
88 return false;
89 }
90
91
92
93 bool CStack::PushStack(int a)
94 {
95 pNode pNodeTemp = new Node;
96
97 if(pNodeTemp != NULL)
98 {
99 pNodeTemp->a = a;
100 pNodeTemp->pNext = NULL;
101
102 if(m_pHead == NULL)
103 {
104 m_pHead = pNodeTemp;
105 }
106 else
107 {
108 pNodeTemp->pNext = m_pHead;
109
110 m_pHead = pNodeTemp;
111 }
112
113 m_iNodeCount++;
114
115 return true;
116 }
117
118 return false;
119 }
120
121
122
123 bool CStack::PopStack(int& a)
124 {
125 if(IsEmpty())
126 {
127 return false;
128 }
129 pNode pNodeDel = m_pHead;
130
131 a = m_pHead->a;
132
133 m_pHead = pNodeDel->pNext;
134
135 delete pNodeDel;
136
137 pNodeDel = m_pHead;
138
139 m_iNodeCount--;
140
141 return true;
142 }
143
144 int CStack::GetTop()
145 {
146 return m_pHead->a;
147 }
148 int CStack::GetLength()
149 {
150 return m_iNodeCount;
151 }
152
153 void CStack::DestroyStack()
154 {
155 pNode pNodeDel = m_pHead;
156
157 while(pNodeDel != NULL)
158 {
159 m_pHead = pNodeDel->pNext;
160
161 delete pNodeDel;
162
163 pNodeDel = m_pHead;
164
165 m_iNodeCount--;
166 }
167 }
168
169 /***********************************/
170 //判断优先级函数
171 //先左后右
172 //先乘除后加减
173 //先括号内,再括号外
174 /***********************************/
175
176 //括号的优先级应该是最高的
177 //然后是* / > + -
178 //最后是遵循从左往右
179 //+,-,*,/的优先级均 低于 '(' ,但是均高于')';
180
181 int Precede(int cur,int sta) //cur 当前的运算符 sta 栈顶元素运算符
182 {
183 char f = 0;
184 switch(cur)
185 {
186 case '+': //判断前面的运算符 ( + -优先级一样 )
187 case '-':
188 {
189 if(sta=='\n' || sta=='(') //若为空 或者 ( 就压栈
190 {
191 f = '<';
192 }
193 else //否则,进行计算
194 {
195 f = '>';
196 }
197
198 break;
199 }
200
201 case '*':
202 case '/':
203 {
204 if(sta=='*'||sta=='/'||sta==')') //遇到'*' , '/' 或')' 进行计算
205 {
206 f = '>';
207 }
208 else //其他情况压栈
209 {
210 f = '<';
211 }
212
213 break;
214 }
215 case '(':
216 {
217 if(sta==')') //不可能会存在 )( 这种情况
218 {
219 cout<<"Error"<<endl;
220
221 exit(0);
222 }
223 else
224 {
225 f = '<'; //遇到其他情况全部压栈
226 }
227 break;
228 }
229
230 case ')':
231 {
232 switch(sta)
233 {
234 case '(':
235 {
236 f = '=';
237 break;
238 }
239 case '\n':
240 {
241 cout<<"Error."<<endl;
242
243 exit(0);
244 break;
245 }
246 default: //遇到此情况,均进行计算
247 {
248 f = '>';
249 break;
250 }
251 }
252
253 break;
254 }
255
256 case '\n': //'\n'一般为表达式结尾的标志了。
257 {
258 switch(sta)
259 {
260 case '\n':
261 {
262 f = '=';
263 break;
264 }
265 case '(':
266 {
267 cout<<"Error."<<endl;
268
269 exit(0);
270 }
271 default:
272 {
273 f = '>';
274
275 break;
276 }
277 }
278
279 break;
280 }
281 }
282
283 return f;
284 }
285 int EvaluateExpression()
286 {
287
288 CStack TableOper; //符号栈 (用来存运算符)
289 CStack TableNum; //数组栈 (用来存数字)
290
291 TableOper.InitStack();
292 TableNum.InitStack();
293
294 TableOper.PushStack('\n');
295
296 char a = 0; //存放当前的运算符
297
298 int i = 0; //存放操作数1
299 int j = 0; //存放操作时2
300 int x = 0; //存放TablePer栈中的栈顶元素所代表的运算符
301
302 int PreFlag = TableOper.GetTop();
303 int NowFlag = TableOper.GetTop();
304
305
306 a = getchar(); //先接受一个字符
307
308 x = TableOper.GetTop();
309
310
311
312 while(a!='\n' || x!= '\n')
313 {
314
315
316
317 /**********判断是否是运算符**********/
318 if(IsOper(a))
319 {
320 char f = Precede(a,x); //进行优先级判断
321
322 switch(f)
323 {
324 case '<': //如果当前运算符比栈中的运算符优先级低
325 {
326 TableOper.PushStack(a); //那么将当前运算符a 压入栈
327
328 a = getchar(); //接受下一个字符
329
330 NowFlag = TableOper.GetTop(); //NowFlag变为新压入栈的运算符
331
332 break;
333 }
334 case '>': //如果当前运算符比栈中的运算符优先级高
335 {
336
337 TableOper.PopStack(x); //将TableOper(符号栈)栈顶的 运算符 弹出栈,准备作为运算符
338
339 PreFlag = TableOper.GetTop(); //PreFlag为前一个运算符
340
341 TableNum.PopStack(i); //将TableNum(数字栈)的两个待计算的操作数 弹出栈,并分别赋给i,j;
342
343 TableNum.PopStack(j);
344
345 TableNum.PushStack(Result(i,x,j)); // 将计算完毕的结果再压栈压回TableNum中
346
347 break;
348
349 }
350 case '=': //如果优先级相等
351 {
352
353 TableOper.PopStack(x); //TableOper中的栈顶 运算符 弹栈 给 x, 作为 待 操作的运算符
354
355 a = getchar(); //接受新的字符
356
357 break;
358 }
359 }
360 }
361
362 /**********判断是否是数字**********/
363 else if(a >= '0' && a <= '9')
364 {
365 if(PreFlag == NowFlag) //如果前后的符号标记相等,(即意味着一直在输入数字,如 12 + 34,这里的12 = 1*10 + 2)
366 {
367 if(!TableNum.IsEmpty()) //如果当前的TableNum 数字栈 不为空
368 {
369 int Temp = 0;
370
371 TableNum.PopStack(Temp); //先将前一个被压入TableNum栈的数字弹出给Temp (如弹出1)
372
373 Temp *= 10; //Temp *= 10 (Temp = 10)
374
375 Temp = Temp + a - 48; //Temp 再加上现在的a ,再进去48 (Temp = 10 + 'a' -48 = 10 + 50 - 48 = 12)
376
377 TableNum.PushStack(Temp); //再将Temp 压回到 数字栈
378
379 a = getchar(); //再读入字符
380 }
381
382
383 else //反之,若为空,也就是数字栈中没有数
384 {
385 TableNum.PushStack(a-48); //直接将a-48 压入 数字栈
386
387 a = getchar(); //再读入字符
388 }
389 }
390
391 else //如果前后的符号标记不相等,(即意味着,输入的数字中间有间隔 运算符 如 1 + 2)
392 {
393 PreFlag = NowFlag; //把PreFlag 置为 当前的 运算符
394
395 TableNum.PushStack(a-48); //直接将a-48 压入 数字栈
396
397 a = getchar(); //再读入字符
398
399 }
400 }
401
402 /**********都不是,说明输入的表达式有误**********/
403 else
404 {
405 cout<<"error"<<endl;
406
407 exit(0);
408
409 }
410
411 x = TableOper.GetTop();
412
413 }
414
415
416 int ans = 0; //定义一个answer,作为结果返回
417
418 TableNum.PopStack(ans);
419
420
421 return ans;
422 }
423
424
425
426
427 bool IsOper(int a) //判断是否是运算符,这里只是 + - * / ( ) \n
428 {
429 switch(a)
430 {
431 case '+':
432 case '-':
433 case '*':
434 case '/':
435 case '(':
436 case ')':
437 case '\n':
438 {
439 return true;
440 }
441
442 default:
443 {
444 return false;
445 }
446 }
447 }
448
449 int Result(int i,int Opr,int j) //计算两个数直接的运算结果
450 {
451 switch(Opr)
452 {
453 case '+':
454 return i+j;
455 case '-':
456 return j-i;
457
458 case '*':
459 return j*i;
460 case '/':
461 return j/i;
462
463 default:
464 return-1;
465 }
466
467 }