/*题目描述
读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
输入
测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。
输出
对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。*/
#include<iostream>
#include<cstdio>
#include<queue>
#include<stack>
#include<map>
#include<string>
using namespace std;
struct node{
double value;//后续有除法
char ch;
bool flag;
};
string str;
queue <node> v;
stack <node> s;
map<char,int> op;
void change(){//将中缀表达式转换为后缀表达式
int i;
struct node temp;
for(i=0;i<str.length();){//第三个位置不能填i++ 循环体里有自增操作
if(str[i]>='0'&&str[i]<='9'){
temp.flag=1;
temp.value=str[i++]-'0';
while(str[i]>='0'&&str[i]<='9'&&i<str.length()){//防止自增使i越界
temp.value=temp.value*10+(str[i++]-'0');
}
v.push(temp);
}else{
temp.flag=0;
while(op[str[i]]<=op[s.top().ch]&&s.empty()==0){//要判断操作符栈是否非空
v.push(s.top());
s.pop();
}
temp.ch=str[i++];
s.push(temp);
}
}
while(s.empty()==0){//操作符栈中可能还剩下操作符
v.push(s.top());
s.pop();
}
}
double cal(){//计算后缀表达式
double f1,f2;
struct node temp1,temp2;
while(v.empty()==0){
temp1=v.front();
v.pop();
if(temp1.flag==1)s.push(temp1);
else{
f2=s.top().value;
s.pop();
f1=s.top().value;
s.pop();
if(temp1.ch=='+'){
temp2.value=f1+f2;
}else if(temp1.ch=='-'){
temp2.value=f1-f2;
}else if(temp1.ch=='*'){
temp2.value=f1*f2;
}else if(temp1.ch=='/'){
temp2.value=f1/f2;
}
temp2.flag=1;
s.push(temp2);
}
}
return s.top().value;
}
int main(){
op['+']=1;
op['-']=1;
op['*']=2;
op['/']=2;
while(getline(cin,str)&&str!="0"){//getline不能写!=EOF "0"要用双引号
int i;
//for(i=str.length()-1;i>=0;i--){
// if(str[i]==' ')str.erase(i,i+1);
//}
string::iterator it;
for(it=str.end();it!=str.begin();it--){
if(*it==' ')str.erase(it);
}
while(s.empty()==0)s.pop();
change();
printf("%.2f\n",cal());
}
return 0;
}
编译器没有报错,但是运行后没有输出
运行的画面发一下截图
这这这,感觉你写的好复杂的样子。