/*
参考大神nb的代码,感觉思路不错!终于搞明白了!一开始不明白在计算表达式的时候,利用栈到底做了什么!现在感觉我们利用栈就是模拟我们书面上计算表达式,
将优先级高的运算先计算出来,然后放进栈中,等待下一次的计算
*/
#include<iostream>
#include<string>
#include<stack>
#include<cstdio>
using namespace std;
class node
{
public:
double ret;
string prefix, suffix;//前缀表达式和后缀表达式
node()
{
ret=0;
prefix=suffix="";
}
};
stack<node>optd;//操作数栈
stack<char>optr;//操作符栈
char formula[1000];//表达式以"=" 结束
int cmp(char ch)//定义符号的优先级
{
switch(ch)
{
case '#': return -2;
case '=': return -1;
case '+':
case '-': return 1;
case '*':
case '/': return 2;
case '(': return 3;
case ')': return 0;
}
return -2;
}
double deal(double x, char ch, double y)
{
switch(ch)
{
case '+': return x+y;
case '-': return x-y;
case '*': return x*y;
case '/': return x/y;
}
return 0.0;
}
void cal()
{
int i=0, n;
node num, aTmp, bTmp;
while(optr.top()!='=')
{
if(formula[i]>='0' && formula[i]<='9')
{
sscanf(formula+i, "%lf%n", &num.ret, &n);
num.prefix.assign(formula+i, n);
num.suffix.assign(formula+i, n);
i+=n;
optd.push(num);
}
else
{
if(optr.top()=='(' && formula[i]==')')//消除一对括弧
{
optr.pop();
++i;
}
if(cmp(formula[i]) > cmp(optr.top()) || optr.top()=='(')//当前运算符大于栈顶运算符直接进栈
{
optr.push(formula[i]);
++i;
}
else
{
char ch=optr.top(), preTmp[]={ch, ' ', '\0'}, sufTmp[]={' ', ch, '\0'} ;
optr.pop();//弹出一个栈顶操作符
bTmp=optd.top(); optd.pop();//得到第二个操作数
aTmp=optd.top(); optd.pop();//得到第一个操作数
aTmp.ret=deal(aTmp.ret, ch, bTmp.ret);
aTmp.suffix+=" " + bTmp.suffix + sufTmp;//得到运算后的后缀式子
aTmp.prefix=preTmp + aTmp.prefix + " " + bTmp.prefix;//得到运算前的后缀式子
optd.push(aTmp);//不要忘记将计算的结果放入栈中
}
}
}
optr.pop();//别忘记弹出栈顶上的'='
}
int main()
{
optr.push('#');//初始化栈顶操作符是‘#’
while(cin>>formula)
{
cal();
node ans=optd.top(); optd.pop();
cout<<"表达式结果:"<<ans.ret<<endl<<"前缀试:"<<ans.prefix+'='<<endl<<"后缀试:"<<ans.suffix+'='<<endl;
}
return 0;
}