【链性栈】表达式求值

  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 }

 

posted @ 2013-10-27 19:53  Geekers  阅读(525)  评论(0编辑  收藏  举报