题目描述
读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
输入描述:
测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。
输出描述:
对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
示例1
输入
1 + 2 4 + 2 * 5 - 7 / 11 0
输出
3.00 13.36
题解:
参考算法笔记上的题解
AC代码:
#include <iostream>
#include <stdio.h>
#include<map>
#include<string>
#include<stack>
#include<queue> //存放后缀表达式
using namespace std;
struct Node{
char op;
double num;
bool flag; //flag=true 证明是数字
};
map<char,int> op;
queue<Node> q;
stack<Node> s;
string str;
//中缀表达式转换成后缀表达式
void Change(){
Node t;
double tmp; //一开始这里的double变量定义成了int
char c;
for(int i=0;i<str.length();){
if(str[i]>='0' && str[i]<='9'){
tmp=str[i++]-'0';
while(str[i]>='0' && str[i]<='9' && i<str.length()){
tmp=tmp*10+str[i++]-'0';
}
t.flag= true;
t.num=tmp;
q.push(t);
}
else{
//操作符
c=str[i];
while( !s.empty() && op[c]<=op[s.top().op]){
q.push(s.top());
s.pop();
}
t.flag= false;
t.op=c;
s.push(t); //这个操作符是要入栈的
i++;
}
}
while(!s.empty()){
q.push(s.top());
s.pop();
}
}
//计算后缀表达式的值
double Cal(){
while(!q.empty()){
Node tp=q.front();
q.pop();
double num1,num2;
if(tp.flag){
s.push(tp); //利用栈计算后缀表达式的值
}
else{
Node res;
num2=s.top().num;
s.pop();
num1=s.top().num;
s.pop();
if(tp.op=='+') res.num=num1+num2;
else if(tp.op=='-') res.num=num1-num2;
else if(tp.op=='*') res.num=num1*num2;
else if(tp.op=='/') res.num=num1/num2;
res.flag=true;
s.push(res);
}
}
return s.top().num;
}
int main(){
//没有括号的加减乘除 整数运算
op['+']=op['-']=1;
op['*']=op['/']=2;
while( getline(cin,str) && str!="0"){
while(!q.empty()) q.pop();
while(!s.empty()) s.pop();
//去除空格
for(string::iterator it=str.begin();it!=str.end();it++){
if(*it==' ')
str.erase(it);
}
Change();
//注意输出格式
printf("%.2f\n",Cal());
// cout<<setprecision(2)<<Cal()<<endl;
}
return 0;
}