中缀表达式的计算(含出错处理,括号处理)

来源:互联网 发布:扭力单位转换软件 编辑:程序博客网 时间:2024/06/05 16:35

原文链接:http://blog.csdn.net/iqrocket/article/details/8136172


以下是一个中缀表达式计算的程序,大体思路是利用两个栈,一个存放操作数,另外一个存放运算符,分别将输入的操作数和运算符存入其中,若输入的运算符优先级小于栈顶的运算符,则将栈顶的运算符取出,并将操作数栈的两个栈顶操作数取出进行运算,将运算结果重新填入栈中,而后将刚才输入的运算符压入运算符栈中。重复上述过程,直到运算符栈的有效运算符为空。

为了区别不同运算符的优先性,我将+-*/的优先级的代号分别设为1、2、4、5。通过比较输入的优先级是否比栈顶的优先级小2及以上来看出输入的优先级是否小于栈顶的优先级。这样既可以唯一表示这四个运算符,也可以保证各自的优先级和运算顺序。  


对于括号,我将待压入栈的左括号的优先级置为最高,这样可以保证左括号可以直接压入栈。


我还使用了表达式的输入错误处理,包括除数为0,括号不配对。

[cpp] view plaincopy
  1. #include <iostream>  
  2. #include <stack>  
  3. #include <cmath>  
  4. #include <string>  
  5. using namespace std;  
  6.   
  7. int main()  
  8. {  
  9.     cout<<"Enter some infix expression,such as 1+1(must be integers,Ctrl+z to end):"  
  10.         <<endl;  
  11.   
  12. start:  string line; //使用标号语句和跳转语句,当输入的表达式非法时可以便捷地跳回到此处,  
  13.                         //重新输入数据  
  14.     while(getline(cin,line))  
  15.     {  
  16.         stack<double> numStack;  
  17.         stack<int> expStack;  
  18.   
  19.         expStack.push(-2);   
  20.   
  21.         string s="";  
  22.         int prop=0,first=0,num=0; //prop表示运算符的优先级  
  23.         double val1=0.0,val2=0.0,result=0.0;  
  24.         char ch;  
  25.       
  26.         //getline(cin,line);  
  27.         line+='#'//自己设置停止时刻  
  28.         for(int i=0;line[i]!='#';++i)  
  29.         {  
  30.             ch=line[i];  
  31.   
  32.             if(isdigit(ch))  
  33.                 s+=ch;  
  34.             else  
  35.             {  
  36.                 //当s不为空时才进行转换  
  37.                 if(s!="")  
  38.                 {  
  39.                     num=atoi(s.c_str());  
  40.                     numStack.push(num);  
  41.                     s=""//将s清空  
  42.                 }  
  43.   
  44.                 if(ch==')')  
  45.                 {  
  46.                     while(expStack.top()!=-2&&expStack.top()!=-7) //还没到栈底,并且不是左括号时  
  47.                     {  
  48.                         first=expStack.top();  
  49.                         expStack.pop();  
  50.           
  51.                         val1=numStack.top();  
  52.                         numStack.pop();  
  53.                         val2=numStack.top();  
  54.                         numStack.pop();  
  55.   
  56.                         switch(first)  
  57.                         {  
  58.           
  59.                         case 1:  
  60.                             result=val2+val1;  
  61.                             break;  
  62.                         case 2:  
  63.                             result=val2-val1;  
  64.                             break;  
  65.                         case 4:  
  66.                             result=val2*val1;  
  67.                             break;  
  68.                         case 5:  
  69.                             //当输入除数为0时可能存入val1的不为0,可能很接近0,只要val1足够接近0就认为是0  
  70.                             if(val1<0.0000001)  
  71.                             {  
  72.                                 cerr<<"The divider can't be 0! input again:"<<endl;  
  73.                                 //exit(1);  
  74.                                 goto start;  
  75.                             }  
  76.                             result=val2/val1;  
  77.                             break;  
  78.                         }  
  79.                         numStack.push(result);  
  80.                     }  
  81.   
  82.                     //将左括号删去  
  83.                     if(expStack.top()==-7)  
  84.                         expStack.pop();  
  85.                     else  
  86.                     {  
  87.                         cout<<"'(' and ')' can't match! input again:"<<endl;  
  88.                         goto start;  
  89.                         //exit(1);  
  90.                     }  
  91.                 }  
  92.   
  93.                 else  
  94.                 {  
  95.                     switch(ch)  
  96.                     {  
  97.                     case '+':  
  98.                             prop=1;  
  99.                             break;  
  100.                     case '-':  
  101.                             prop=2;  
  102.                             break;  
  103.                     case '*':  
  104.                             prop=4;  
  105.                             break;  
  106.                     case '/':  
  107.                             prop=5;  
  108.                             break;  
  109.                     case '(':  
  110.                             prop=7; //左括号栈外的优先级最高,可直接入栈  
  111.   
  112.                     }  
  113.                     first=expStack.top();  
  114.   
  115.                     //说明栈顶符号的优先级大于读入的优先级  
  116.                     if(prop-first<2)  
  117.                     {  
  118.                         expStack.pop(); //除去运算符栈栈顶元素  
  119.   
  120.                         //取出两个操作数  
  121.                         val1=numStack.top();  
  122.                         numStack.pop();  
  123.                         val2=numStack.top();  
  124.                         numStack.pop();  
  125.   
  126.                         switch(first)  
  127.                         {  
  128.                         case 1:  
  129.                             result=val2+val1;  
  130.                             break;  
  131.                         case 2:  
  132.                             result=val2-val1;  
  133.                             break;  
  134.                         case 4:  
  135.                             result=val2*val1;  
  136.                             break;  
  137.                         case 5:  
  138.                             if(0==val1)  
  139.                             {  
  140.                                 cerr<<"The divider can't be 0! input again:"<<endl;  
  141.                                 goto start;  
  142.                                 //exit(1);  
  143.                             }  
  144.                             result=val2/val1;  
  145.                             break;  
  146.                         }  
  147.                         numStack.push(result); //将运算的结果重新压到操作数栈中  
  148.                     }  
  149.   
  150.                     if(7==prop)  
  151.                         expStack.push(-7); //-7是左括号的标志  
  152.                     else  
  153.                         expStack.push(prop); //将新来的运算符压入运算符栈  
  154.                 }  
  155.             }     
  156.         }  
  157.   
  158.         //最后一个输入的操作数单独处理  
  159.         if(s!="")  
  160.         {  
  161.             num=atoi(s.c_str());  
  162.             numStack.push(num);  
  163.         }  
  164.   
  165.   
  166.         //到了expStack的栈顶  
  167.   
  168.         while(expStack.top()!=-2)  
  169.         {  
  170.           
  171.             first=expStack.top();  
  172.   
  173.             //如果还剩左括号时,输出错误信息  
  174.             if(first==-7)  
  175.             {  
  176.                 cout<<"'(' and ')' can't match! input again:"<<endl;  
  177.                 goto start;  
  178.                 //exit(1);  
  179.             }  
  180.   
  181.             expStack.pop();  
  182.           
  183.             val1=numStack.top();  
  184.             numStack.pop();  
  185.             val2=numStack.top();  
  186.             numStack.pop();  
  187.   
  188.             switch(first)  
  189.             {  
  190.           
  191.             case 1:  
  192.                 result=val2+val1;  
  193.                 break;  
  194.             case 2:  
  195.                 result=val2-val1;  
  196.                 break;  
  197.             case 4:  
  198.                 result=val2*val1;  
  199.                 break;  
  200.             case 5:  
  201.                 if(val1<0.0000001)  
  202.                 {  
  203.                     cerr<<"The divider can't be 0! input again:"<<endl; //除数不能为0  
  204.                     goto start;  
  205.                     //exit(1);  
  206.                 }  
  207.                 result=val2/val1;  
  208.                 break;  
  209.             }  
  210.   
  211.             numStack.push(result);  
  212.           
  213.         }  
  214.   
  215.         cout<<"result:"<<numStack.top()<<endl;  
  216.     }  
  217.   
  218.     return 0;  
  219.       
  220.   
  221. }  
0 0