题目描述
读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
输入
测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。
输出
对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
样例输入
30 / 90 - 26 + 97 - 5 - 6 - 13 / 88 * 6 + 51 / 29 + 79 * 87 + 57 * 92
0
样例输出
读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
输入
测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。
输出
对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
样例输入
30 / 90 - 26 + 97 - 5 - 6 - 13 / 88 * 6 + 51 / 29 + 79 * 87 + 57 * 92
0
样例输出
12178.21
很明显是栈的简单应用,大致思路如下:
(1)依次扫描字符串,如是操作数则直接入栈,如是操作符,则进入(2)
(2)若操作符栈为空则直接入栈,否则比较栈顶的操作符与当前的操作符的优先级。若栈顶的优先级较低,操作符直接入栈,否则从操作数栈中弹出2个操作数,从操作符栈中弹出一个操作符进行运算,并把结果入栈。
这里只需注意细节问题,比如回退下标和处理最后一个操作数。具体可参看代码中的注释
#include <iostream>
#include <cstdio>
#include <stack>
using namespace std;
bool isNumber(char v){
return v<='9' && v>='0';
}
bool isOperationChar(char v){
return v=='+' || v=='-' || v=='*' || v=='/';
}
//+-的优先级为0,*/为1
bool getCharPriority(char v){
if(v=='-'||v=='+') return 0;
return 1;
}
//计算2个操作数
double operation(double num1,double num2,char op){
switch(op){
case '+': return num1+num2;
case '-': return num1-num2;
case '*': return num1*num2;
case '/': return num1/num2;
}
}
//从操作数栈中取2个数,从运算符中取符号进行运算并入栈
void calculate(stack<char> &st_char,stack<double> &st_number){
double num2=st_number.top(); st_number.pop();
double num1=st_number.top(); st_number.pop();
char op=st_char.top(); st_char.pop();
double r=operation(num1,num2,op);
st_number.push(r);
}
int main(){
stack<char> st_char; //运算符栈
stack<double> st_number;//操作数栈
string value;
int i,j,len;
while(getline(cin,value),value!="0"){
double sum=0;
len=value.length();
for(i=0;i<len;i++){
if(value[i]==' ')
continue; //跳过空格
if(isNumber(value[i])){
sum=sum*10+value[i]-'0'; //累加操作数
if(i>=len-1){ //最后一个操作数
st_number.push(sum);
while(!st_char.empty()){
calculate(st_char,st_number);
}
}
}else if(isOperationChar(value[i])){
if(sum!=-1) //非回退
st_number.push(sum); //操作数入栈
sum=0; //操作数累加重置
if(st_char.empty()){ //符号栈为空,直接入栈
st_char.push(value[i]);
}else{ //不为空,比较当前符号和栈顶符号的优先级
char op=st_char.top();
if(getCharPriority(op)>=getCharPriority(value[i])){
//若栈顶符号的优先级大于等于当前的符号,则计算后把结果入栈
calculate(st_char,st_number);
i--; //i回退1
sum=-1; //sum=-1 为回退的标志
}else{
st_char.push(value[i]);
}
}
}
}
printf("%.2lf\n",st_number.top()); //最后在操作数栈里面的就是运算结果
}
return 0;
}
题目来源: http://codeup.cn/problem.php?cid=100000602&pid=0