//表达式求值/ / //1、确定是标准的中缀表达式 //2、将中缀表达式转化成后缀表达式 //3、计算后缀表达式的值 / #include <iostream>
#include <string> #include <stack>
using namespace std; //制定运算符优先级 int Priority(char operators) { switch(operators) { case '*': case '/': return 2; case '+': case '-': return 1; case '(': return 0; case '#': return -1; default: return -1; } } //判断是否为运算符 int Isoperator(char ch) { switch(ch) { case '*': case '/': case '+': case '-': return 1; default: return 0; } } //将中缀表达式转换成后缀表达式 void Mid_To_Back(string mid,char back[],int& n) { //mid为中缀表达式,back为后缀表达式,n记录back的长度 int i = 0; n = 0; stack <char> opstack; //存放运算符 int length = mid.size(); opstack.push('#'); //进入栈底作为"哨兵" for(i = 0; i < length; i++) //对mid进行遍历 { if((mid[i] >= '0' && mid[i] <= '9') || mid[i] == '.') { back[n++] = mid[i]; //为数字,直接进入back } else if( Isoperator(mid[i]) ) { //为运算符 back[n++] = ' '; //加入空格以区分数字 while(Priority(mid[i]) <= Priority(opstack.top())) { //优先级不大于栈内运算符 back[n++] = opstack.top(); opstack.pop(); //取栈顶运算符到back,并出栈 } opstack.push(mid[i]);//运算符入栈 } else if('(' == mid[i]) { opstack.push(mid[i]);//为左括号,直接入栈 } else if(')' == mid[i]) { while('(' != opstack.top()) { //为右括号 back[n++] = opstack.top(); opstack.pop(); //将栈内左括号以上的运算符移动到back } opstack.pop(); //将左括号出栈 } else { //...... } } while('#' != opstack.top()) { back[n++] = opstack.top(); opstack.pop(); //将栈内运算符移动到back } } double GetNum(char back[],int& i) { //i为数字后的位置 double x1 = 0.0; //存放整数 double x2 = 0.0; //存放小数 int flag = 1; //判断是否移动到小数点 double k = 10.0; while((back[i] >= '0' && back[i] <= '9') || back[i] == '.') { //一直计算到非数字和小数点(空格和运算符) if(back[i] == '.') { flag = 0; i++; continue; //为小数点,该步不计算 } if(flag) //小数点之前 { x1 = x1*10 + (back[i] - '0'); } else //小数点之后 { x2 += (back[i] - '0') / k; k = k * 10; } i++; } return (x1+x2); } //计算后缀表达式 //后缀表达式里只有数字、运算符、空格 double Calculate(char back[],int n) { //n为back的长度 stack <double> restack; //结果栈 double x1 = 0.0; //每次运算前一个数字 double x2 = 0.0; //每次运算后一个数字 int i = 0; for( ; i < n; i++) { if(back[i] >= '0' && back[i] <= '9') { //为数字,进入结过栈 restack.push(GetNum(back,i)); i--; //由于下一步i++,这里减1 } else if(' ' == back[i]) { //空格 continue; } else { //运算符 switch(back[i]) { //在结果栈里取出两个作运算 case '+': //再将计算结果入结果栈 { x2 = restack.top(); restack.pop(); x1 = restack.top(); restack.pop(); restack.push(x1+x2); break; } case '-': { x2 = restack.top(); restack.pop(); x1 = restack.top(); restack.pop(); restack.push(x1-x2); break; } case '*': { x2 = restack.top(); restack.pop(); x1 = restack.top(); restack.pop(); restack.push(x1*x2); break; } case '/': { x2 = restack.top(); restack.pop(); x1 = restack.top(); restack.pop(); restack.push(x1/x2); break; } default:break; } } } //现在栈内只有一个数字 return restack.top(); //就是后缀表达式的值 } int main() { string mid; cin>>mid; char back[100]; int n = 0; Mid_To_Back(mid,back,n); cout<<"后缀表达式为:"; for(int i = 0; i < n; i++) { cout<<back[i]; } cout<<endl; cout<<"计算结果为:"; cout<<Calculate(back,n)<<endl; return 0; }