表达式求值

来源:互联网 发布:jsp获取js变量值 编辑:程序博客网 时间:2024/05/16 19:50

参考王道计算机机试指南

利用堆栈对表达式求值

1.设立两个堆栈,一个用于保存运算符,一个用于保存数字

2.在表达式的首位添加标记运算符,该运算符的优先级最低

3.从左至右遍历表达式,若遍历到运算符,则将该运算符与栈顶运算符进行比较,若栈顶运算符的优先级低或栈为空栈,则将运算符入栈。遍历字符串中的下一个元素

4.若栈顶运算符优先级大于当前遍历到的运算符的优先级,将运算符栈栈顶元素弹出栈,并从数字栈弹出两个数字,完成相应的运算后将结果压入数字栈,

5.若遍历到数字,则直接将数字压入数字栈

6.若运算符栈中只有两个元素,且栈顶元素为我们标记的运算符,那么表达式结束。数字栈中只有一个数字,就是我们要求的答案

#include <stack>#include <stdio.h>using namespace std;char str[220];//保存表达式字符串int mat[][5] = {//优先级矩阵,若mat[i][j]==1,则表示i号运算符优先级大于j号//运算符,运算编码规则为+为1号,-为2号,*为3号,/为4号,我们人为添加的为0号1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,1,1,0,0,1,1,1,0,0};stack<int> op;//运算栈符,保存运算符编号stack<double> in;//数字栈void getOp(bool &reto,int &retn,int &i)//获取表达式中下一个元素函数{if(i == 0&&op.empty() == true||str[i] == 0)//若此时遍历字符串第一个字符,且运算栈为空,我们人为添加编号为0的标记字符{reto = true;//为运算符retn = 0;//编号为0的标记字符return;//返回}if(str[i]>='0'&&str[i]<='9'){reto = false;//返回为数字}else{reto = true;//返回为运算符if(str[i]=='+'){retn = 1;}else if(str[i] == '-'){retn = 2;}else if(str[i] == '*'){retn = 3;}else if(str[i] == '/'){retn = 4;}i +=2;//i递增,跳过该运算符和该运算符后的空格return;}retn = 0;//返回结果为数字for(;str[i]!= ' '&&str[i]!=0;i++)//计算该数字的数字值{retn +=10;retn +=str[i]-'0';}if(str[i] ==' ')//若其后字符为空格,则表示字符串未被遍历完i++;return;}int main(){while(gets(str)){if(str[0] == '0'&&str[1] == 0)//若输入只有一个0,则退出break;bool retop;int retnum;int idx = 0;//定义遍历到的字符串下标,初始值为0while(!op.empty())op.pop();while(!in.empty())in.pop();while(true)//循环遍历表达式字符串{getOp(retop,retnum,idx);if(retop == false)//若该元素为数字{in.push((double)retnum);}else{double tmp;if(op.empty()==true||mat[retnum][op.top()]==1){op.push(retnum);}else{while(mat[retnum][op.top()] == 0){int ret = op.top();op.pop();double b = in.top();in.pop();double a = in.top();in.pop();if(ret == 1)tmp = a+b;else if(ret == 2)tmp = a-b;else if(ret == 3)tmp = a*b;elsetmp = a/b;in.push(tmp);}op.push(retnum);//将当前运算符压入运算符堆栈}}if(op.size() == 2&&op.top() == 0)//若运算符堆栈只有两个元素,且其栈顶元素为标记运算符,则表达式求值结束break;}printf("%.2f\n",in.top());//输出数字栈中唯一的数字}return 0;}

0 0