题解 | #简单计算器#
简单计算器
http://www.nowcoder.com/practice/5759c29a28cb4361bc3605979d5a6130
1、求解本题时,最好提前学习中缀表达式转后缀表达式+求值这部分的内容,那么理解下面代码某些部分的内容会更加得心应手。 2、要注意输出的是精确到小数位后两位的小数,因此我们在编程过程中切忌int、float、double的混用,最好统一起来,否则最后的输出会因位数问题而截断,从而你只能得到0.00这个答案,具体原因请学习计算机组成原理中数制相关内容。
#include<iostream>
#include<string>
#include<stdio.h>
#include<stack>
#include<cctype>
using namespace std;
int Oper_order(char a){ //运算符次序
if(a=='#')
return 0;
else if(a=='$')
return 1;
else if(a=='+' || a=='-')
return 2;
else
return 3;
}
double GetNum(string s,int &index){ //在表达式中取数
double temp=0;
while(isdigit(s[index])){
temp=temp*10+s[index]-'0';
index++;
}
return temp;
}
double Calculate(double x1,double y1,char o){ //计算求值
double r=0;
if(o=='-')
r=x1-y1;
else if(o=='+')
r=x1+y1;
else if(o=='*')
r=x1*y1;
else if(o=='/')
r=x1/y1;
return r;
}
int main(){
string s;
while(getline(cin,s)){
int index=0; //该索引为全局变量,记录要求表达式的当前索引位置
if(s=="0")
break;
stack<double> data;
stack<char> oper;
s+="$"; //字符串尾部加入“$”,优先级次低,这样程序能正常结束,并且也能正常入栈,
//(因为我们要弹出的是优先级大于等于当前运算符的栈中运算符,而到了最后运算符栈中只剩了#)
oper.push('#'); //运算符栈中加入该特殊字符,并将其优先级设为最低,这样任何运算符都入栈。
while(index<s.size()){
if(s[index]==' ')
index++;
else if(isdigit(s[index])){
data.push(GetNum(s,index)); //若为数字则加入运算数栈
}
else{ //若为运算符则进行如下处理
if(Oper_order(oper.top())<Oper_order(s[index])){ //若当前运算符栈顶的运算符优先级小于当前扫描到的运算符时直接将其入栈
oper.push(s[index]);
index++;
}
else{ //若当前运算符栈顶的运算符优先级大于等于当前扫描到的运算符时,弹出两个操作数进行运算
double y=data.top(); //注意先弹出的是右操作数(具体原因请学习中缀表达式转后缀表达式并求值这部分的内容)
data.pop();
double x=data.top();
data.pop();
data.push(Calculate(x,y,oper.top()));
oper.pop();
}
}
}
printf("%.2f\n",data.top());
}
}