使用双栈实现表达式求值

算法要点:

1) 采用双栈,一个栈用来保存运算符,一个栈用来保存数据

2) 符号优先级设置

  i(+ -)< (* /) 

  ii 相同运算符,栈内优先级高于栈外优先级

  ii 对于栈内:左括号的优先级最高 右括号优先级仅高于'#'

  ii 对于栈外:与上面相反

 3)计算时机

   当栈内运算符优先级 > 栈外运算符优先级:可以计算,计算结果压入数据栈

   当栈内运算符优先级 < 栈外运算符优先级:栈外运算符压入运算符栈

   当栈内运算符优先级 = 栈外运算符优先级:只可能是左括号和右括号的情况,将左括号

                                                              出栈即可

 

算法理解建议:

输入一个简单的表达式,最好包含括号的情况,然后单步调试,跟踪两个栈的数据变化情况

 

算法实现(包括测试代码):

  1. /************************************************************************/  
  2. /* 表达式  求值                                                                     */  
  3. /************************************************************************/  
  4.   
  5. #include <iostream>   
  6. #include <stack>   
  7.   
  8. using namespace std;  
  9.   
  10. //符号数组   
  11. char symbol[7] = {'+''-''*''/''('')''#'};  
  12. //栈内元素的优先级   
  13. int in[7] = {3, 3, 5, 5, 1, 6, 0};  
  14. //栈外元素的优先级   
  15. int out[7] = {2, 2, 4, 4, 6, 1, 0};  
  16. /* 
  17.  * 通过符号字符获取它的数组下标 
  18.  */  
  19. int get(char c)  
  20. {  
  21.     switch(c)  
  22.     {  
  23.     case '+':  
  24.         return 0;  
  25.     case '-':  
  26.         return 1;  
  27.     case '*':  
  28.         return 2;  
  29.     case  '/':  
  30.         return 3;  
  31.     case '(':  
  32.         return 4;  
  33.     case ')':  
  34.         return 5;  
  35.     case '#':  
  36.         return 6;  
  37.     default:   
  38.         return 6;  
  39.     }  
  40. }  
  41.   
  42. /* 
  43.  * 比较栈内运算符c1和栈外运算符c2的优先级 
  44.  */  
  45. char precede(char c1, char c2)  
  46. {  
  47.     int i1 = get(c1);  
  48.     int i2 = get(c2);  
  49.   
  50.     if(in[i1] > out[i2])  
  51.     {  
  52.         return '>';  
  53.     }  
  54.     else if(in[i1] < out[i2])  
  55.     {  
  56.         return '<';  
  57.     }  
  58.     else  
  59.     {  
  60.         return '=';  
  61.     }  
  62. }  
  63.   
  64. /* 
  65.  * 计算基本表达式的值 
  66.  */  
  67. int figure(int a, int theta, int b)  
  68. {  
  69.     switch(theta)  
  70.     {  
  71.     case 0:  
  72.         return a + b;  
  73.     case 1:  
  74.         return a - b;  
  75.     case 2:  
  76.         return a * b;  
  77.     default:  
  78.         return a / b;  
  79.     }  
  80. }  
  81.   
  82. /* 
  83.  * 计算表达式的值 
  84.  */  
  85. int EvaluateExpression(const char *exp)  
  86. {  
  87.     stack<int> data; //数据栈   
  88.     stack<int> oper; //符号栈   
  89.       
  90.     oper.push(get('#'));  
  91.     int sum = 0;  
  92.     int flag = 1; //表示正负号 1,表示正 0,表示负   
  93.     int a, theta, b;  
  94.   
  95.     if(!('+' == *exp || '-' == *exp || '(' == *exp || isdigit(*exp)))  
  96.     {  
  97.         cout << "表达式出错1" << endl;  
  98.         return -1;  
  99.     }  
  100.   
  101.     if('-' == *exp)  
  102.     {  
  103.         flag = 0;  
  104.         exp++;//指向下一个字符   
  105.     }  
  106.   
  107.     int index = oper.top();  
  108.     while(*exp || symbol[index] != '#')  
  109.     {  
  110.         if(isdigit(*exp))  
  111.         {  
  112.             sum = 0;  
  113.             if(flag)  
  114.             {  
  115.                 while(isdigit(*exp))  
  116.                 {  
  117.                     sum = sum * 10 + *exp - '0';  
  118.                     exp++;  
  119.                 }  
  120.             }  
  121.             else  
  122.             {  
  123.                 while(isdigit(*exp))  
  124.                 {  
  125.                     sum = sum * 10 - *exp - '0';  
  126.                     exp++;  
  127.                 }  
  128.             }  
  129.   
  130.             data.push(sum);  
  131.             flag = 1;  
  132.         }  
  133.         else  
  134.         {  
  135.             switch(precede(symbol[oper.top()], *exp))  
  136.             {  
  137.             case '>' :  
  138.                 b = data.top();  
  139.                 data.pop();  
  140.                 a = data.top();  
  141.                 data.pop();  
  142.                 theta = oper.top();  
  143.                 oper.pop();  
  144.                 data.push(figure(a, theta, b));  
  145.                 break;  
  146.             case '<' :  
  147.                 oper.push(get(*exp));  
  148.                 if(*exp)  
  149.                 {  
  150.                     exp++;  
  151.                 }  
  152.                 break;  
  153.             case '=' :  
  154.                 oper.pop();  
  155.                 if(*exp)  
  156.                 {  
  157.                     exp++;  
  158.                 }  
  159.                 break;  
  160.             }  
  161.         }  
  162.         index = oper.top();  
  163.     }  
  164.   
  165.     return data.top();  
  166. }  
  167.   
  168. int main()  
  169. {  
  170.     cout << EvaluateExpression("((8+6)*2-8)/2") << endl;  
  171.     system("pause");  
  172.     return 0;  
  173. }  

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用 C++ 语言实现双栈表达式求值代码: ```cpp #include <iostream> #include <stack> #include <string> using namespace std; int calculate(string expression) { stack<char> operator_stack; stack<int> operand_stack; unordered_map<char, int> precedence = {{'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}}; auto evaluate = [&]() { char op = operator_stack.top(); operator_stack.pop(); int operand2 = operand_stack.top(); operand_stack.pop(); int operand1 = operand_stack.top(); operand_stack.pop(); int result; switch (op) { case '+': result = operand1 + operand2; break; case '-': result = operand1 - operand2; break; case '*': result = operand1 * operand2; break; case '/': result = operand1 / operand2; break; } operand_stack.push(result); }; for (char token : expression) { if (isdigit(token)) { operand_stack.push(token - '0'); } else if (token == '+' || token == '-' || token == '*' || token == '/') { while (!operator_stack.empty() && operator_stack.top() != '(' && precedence[token] <= precedence[operator_stack.top()]) { evaluate(); } operator_stack.push(token); } else if (token == '(') { operator_stack.push(token); } else if (token == ')') { while (operator_stack.top() != '(') { evaluate(); } operator_stack.pop(); } } while (!operator_stack.empty()) { evaluate(); } return operand_stack.top(); } int main() { string expression = "3*(4+5)-2/(7-3)"; int result = calculate(expression); cout << "The result of " << expression << " is " << result << endl; return 0; } ``` 这个程序使用了 STL 中的 stack 容器来实现操作符和操作数。我们还使用了一个无序映射 unordered_map 来存储不同操作符的优先级。在程序的主函数中,我们调用 calculate 函数来计算表达式的值。在 calculate 函数内部,我们定义了一个 lambda 表达式 evaluate,用于弹出操作符顶的操作符并弹出操作数顶的两个操作数,计算结果并将结果压入操作数。然后我们循环扫描表达式的每个字符,如果是数字,就将其压入操作数;如果是操作符,就比较其与操作符顶的运算符优先级,如果该运算符优先级低于顶运算符,则将顶运算符弹出并弹出操作数顶的两个操作数,计算结果并将结果压入操作数,直到该运算符优先级大于顶运算符或者为空时,将该运算符压入中;如果是左括号,就将其压入操作符;如果是右括号,就依次弹出操作符顶的操作符并弹出操作数顶的两个操作数,计算结果并将结果压入操作数,直到遇到左括号。最后,我们处理剩余的操作符,直到操作符为空,最终操作数中仅有一个数,即为表达式的值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值