描述
读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
输入描述:
测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。
输出描述:
对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
示例1
输入:
1 + 2
4 + 2 * 5 - 7 / 11
0
输出:
3.00
13.36
题解
#include <cstdio>
#include <stack>
#include <string>
#include <map>
#include <iostream>
using namespace std;
int main(){
char buf[300];
map<char,int> priority = { //记录运算符号优先级
{'$',0},
{'+',1},{'-',1},
{'*',2},{'/',2},
};
while (fgets(buf,300,stdin) != NULL){
string expr = buf;
expr.pop_back(); //清楚末尾换行
if(expr == "0"){
break;
}
expr.push_back('$'); //补充虚拟的终止符
string num; //收集单个数字0-9 以组成多位数字
stack<double> numStack;
stack<char> operStack;
for(unsigned i = 0;i < expr.size();i++){
if(expr[i] >= '0' && expr[i] <= '9'){
num.push_back(expr[i]);
} else if(expr[i] == ' '){
if(num != ""){ //当num不为空,即收集到了数字时
numStack.push(stod(num)); //stod:string to double
num = ""; //num重置为空
}
} else{
// expr[i]为符号:+ - * / $
//1.若为$
if(expr[i] == '$'){
if(num != ""){
numStack.push(stod(num));
num = "";
}
}
//2.其他运算符
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;
}
}
//此时比expr[i]优先级更高的运算符都计算过
operStack.push(expr[i]);
}
}
printf("%.2f\n",numStack.top()); //输出结果保留两位小数
}
}