题目给出的是中缀表达式,所以要计算它的值主要是两个步骤:
下面分别讲一下这两步。
中缀表达式转后缀表达式
①设立一个操作符栈,用以临时存放操作符;设立一个数组或者队列,用以存放后缀表达式。
②从左至右扫描中缀表达式,如果碰到操作数(注意:操作数可能不止一位,因此需要一位一位读入然后合并在一起),就把操作数加入后缀表达式中。
③如果碰到操作符op,就将其优先级与操作符栈的栈顶操作符的优先级比较。
④重复上述操作,直到中缀表达式扫描完毕,之后若操作符栈中仍有元素,则将它们依次弹出至后缀表达式中。
本题没有出现括号,但是如果出现括号,处理方法也很简单,只需要在步骤3的a与b之前判断,如果是左括号‘(‘,就压入操作符栈;如果是右括号‘)‘,就把操作符栈里的元素不断弹出到后缀表达式直到碰到左括号‘(‘,然后把左括号‘(‘出栈。
注意除法可能导致浮点数,因此操作数类型要设成浮点型。
用两个栈,一边入栈一边计算。
stack<double> num;
stack<char> opt;
map<char,int> level;
string s;
void calc(char op)
{
double x=num.top();
num.pop();
double y=num.top();
num.pop();
if(op == ‘+‘) num.push(x+y);
if(op == ‘-‘) num.push(y-x);
if(op == ‘*‘) num.push(x*y);
if(op == ‘/‘) num.push(y/x);
}
int main()
{
level[‘+‘]=level[‘-‘]=1;
level[‘*‘]=level[‘/‘]=2;
while(getline(cin,s))
{
if(s == "0") break;
while(num.size()) num.pop();
while(opt.size()) opt.pop();
for(int i=0;i<s.size();i++)
if(isdigit(s[i]))
{
int j=i;
int res=0;
while(j<s.size() && isdigit(s[j]))
{
res=res*10+s[j]-‘0‘;
j++;
}
num.push(res);
i=j-1;
}
else if(s[i] != ‘ ‘)
{
while(opt.size() && level[opt.top()] >= level[s[i]])
{
calc(opt.top());
opt.pop();
}
opt.push(s[i]);
}
while(opt.size())
{
calc(opt.top());
opt.pop();
}
printf("%.2f\n",num.top());
}
//system("pause");
return 0;
}
原文:https://www.cnblogs.com/fxh0707/p/14416729.html