读入一个只包含 +, -, *, 的非负整数计算表达式,计算该表达式的值。
输入描述:
测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。
输出描述:
对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
示例1
输入
1 + 2 4 + 2 * 5 - 7 / 11 0
输出
3.00 13.36
#include <iostream>
#include <string>
#include <stack>
#include <map>
using namespace std;
//表达式解析
//遍历整个字符串 string->int
//两个栈 分别存中间结果,运算符
//newoper优先级低或相等 栈内运算符元素及数字弹栈 之后再将低运算符压入栈中
// newoper优先级高压栈
int main() {
char buf[300];
//优先级 *、/、+、—、$
map<char,int> priority={ {'$',0},
{'+',1},{'-',1},
{'*',2},{'/',2}
};
while (fgets(buf,300,stdin)!=NULL){//需要读入空格,不能用scanf
string expr=buf;//转为字符串
expr.pop_back();//去掉换行
if(expr=="0"){
break;//输入0 整个结束
}
expr.push_back('$');//补充虚拟终止符
string num;//字符串转为数字
stack<double> numstack;//存中间结果
stack<char> operstack;//存运算符
//遍历字符串
for(unsigned i=0;i<expr.size();i++){
if(expr[i]>='0' && expr[i]<='9'){//是数字 放入string类型的num
num.push_back(expr[i]);
}else if(expr[i]==' '){//是空格
if(num!=""){
numstack.push(stod(num));//string->int 转换压入栈中
num="";
}
}else{//+-*/$
if(expr[i]=='$'){
if(num!=""){
numstack.push(stod(num));
num="";
}
}
//运算符优先级低 栈非空 栈顶元素>=新运算符
while (!operstack.empty() && priority[operstack.top()]>=priority[expr[i]]){
char oper=operstack.top();
operstack.pop();//栈顶元素弹出
double rhs=numstack.top();//数字栈弹出栈顶元素 为右操作数
numstack.pop();
double lhs=numstack.top();//数字栈弹出栈顶元素 为右操作数
numstack.pop();
//运算中间结果
switch (oper) {
case '+':
numstack.push(lhs + rhs);
break;
case '-':
numstack.push(lhs - rhs);
break;
case '*':
numstack.push(lhs * rhs);
break;
case '/':
numstack.push(lhs / rhs);
break;
}
}
//优先级更高的已运算完成
//将高或低运算符压入栈中
operstack.push(expr[i]);
}
}
printf("%.2lf\n",numstack.top());//输出小数点两位.2 double是lf
}
return 0;
}