该算法将操作数作为一个栈,运算符作为一个栈
1. 首先置操作数栈为空栈,表达式起始符'#'作为运算符栈的栈底元素
2. 依次读入表达式中每个字符,若是操作数则进操作数栈,反之进入运算符栈比较后作相应操作,最终得出结果
#include <iostream>
#include <cstdio>
#include <stack>
using namespace std;
stack<char> OPTR; //运算符栈
stack<double> OPND; //操作数栈
//比较运算符(a代表运算符栈顶,b代表当前读入的运算符,以此进行相应的操作)
char Precede(char a,char b)
{
if(a=='+'||a=='-') //比 + -运算符等级低的运算符
{
if(b=='+'||b=='-'||b==')'||b=='#') return '>'; //默认+ -(* /)比本身的等级高(说明没有遇到括号之类的特别操作,直接计算)
else return '<';
}
else if(a=='*'||a=='/') //比* / 运算符等级高的只有括号运算
{
if(b=='(') return '<';
else return '>';
}
else if(a=='(') //当进入括号后,其他运算符都将包括在该括号内(在该括号未结束之前)
{
if(b==')') return '=';
else return '<';
}
else if(a==')') //括号结束 *理论正常输入情况下可能不会存在')'在运算符栈内的情况,因为'('在栈顶时遇到')'会弹出,从而在()运算完后消除出括号
{
return '>';
}
else if(a=='#') //结束标志
{
if(b=='#') return '=';
else return '<';
}
}
int In(char a) //检查是否是运算符
{
return (a=='+'||a=='-'||a=='*'||a=='/'||a=='('||a==')'||a=='#');
}
double Oprator(double a,double b,char opra) //对应的运算符进行对应的操作
{
switch(opra)
{
case '+':
return (a+b);
case '-':
return (a-b);
case '*':
return (a*b);
case '/':
return (a/b);
}
}
int main()
{
OPTR.push('#'); //运算符栈先存入'#'
char ch=getchar();
while(ch!='#'||OPTR.top()!='#') //当读到表达式末尾为'#'且运算符栈顶部也为'#'结束
{
if(!In(ch)){ //当不是运算符时进操作数栈
double sum=0;
while(!In(ch)) //对多位数进行计算读入
{
sum=sum*10+ch-'0';
ch=getchar();
}
OPND.push(sum); //最终结果入栈
}
else
switch(Precede(OPTR.top(),ch))
{
case '<': //栈顶元素优先权低
OPTR.push(ch);ch=getchar();
break;
case '=': //消除括号
OPTR.pop();ch=getchar();
break;
case '>': //运算
char opar;double m,n;
opar=OPTR.top();OPTR.pop();
n=OPND.top(); OPND.pop();
m=OPND.top();OPND.pop();
OPND.push(Oprator(m,n,opar));
break;
}
}
cout<<OPND.top()<<endl; //输出结果
}