题目1019:简单计算器
/*
1.符号栈为空 或优先级高于栈顶 则进 符号栈。是高于啊!!!
2.当while操作符出栈运算完后,当前运算符优先级高于栈顶了,故要运算符需入栈。。别漏了。。。。
*/
#include<stdio.h>
#include<stack>
using namespace std;
stack<double> num;
stack<int> op;
char r[210];
int pri[5][5]=
{
1,0,0,0,0,
1,0,0,0,0,
1,0,0,0,0,
1,1,1,0,0,
1,1,1,0,0
};
bool isDigit(char c)
{
if(c>='0'&&c<='9')
return true;
else
return false;
}
bool isOperator(char d)
{
if(d=='+'||d=='-')
return true;
else if(d=='*'||d=='/')
return true;
else
return false;
}
int str2Op(char e)
{
if(e=='+') return 1;
if(e=='-') return 2;
if(e=='*') return 3;
if(e=='/') return 4;
return NULL;
}
void getCh(bool &tmpO,int &tmpN,int &tmpId) //要么 获得一个操作数 要么 获得一个操作符
{
if(tmpId==0&&op.empty()==true){//第一个必然为数字,此处只是为了方便运算而加额外字符
tmpO=true;tmpN=0; return;
}
if(r[tmpId]==0){
tmpO=true;tmpN=0; return;
}
while(true){ //是为了跳过空格
if(r[tmpId]==' '){
tmpId++;continue;
}
else if(isOperator(r[tmpId])){ //获得一个操作符
tmpO=true;tmpN=str2Op(r[tmpId]);tmpId++;break;
}else{
tmpN=0;
while(isDigit(r[tmpId])){ //获得一个操作数
tmpO=false;tmpN=tmpN*10+r[tmpId]-'0'; tmpId++;
}
// printf("当前数字是:%d ",tmpN);
// printf("\n");
break;
}
}
}
int main()
{
//freopen("G:\\in.txt","r",stdin);
while(gets(r)){ //每次读一行,直到文件尾。
if(r[0]=='0'&&r[1]==0) break; //gets()遇到换行就截止,换行对应存的是0 ;
while(!num.empty()) num.pop();
while(!op.empty()) op.pop();
int id=0; //标记当前读到的位置。
bool isOp; //作为引用,以在函数中修改
int ch; //作为引用,以在函数中修改
while(true){
getCh(isOp,ch,id); //获取当前id开始的一个操作数 OR 一个操作符,跳过空格。
if(isOp==false){ //若为数字直接进数字栈
num.push((double)ch);
// printf("当前数字是:%.2lf ",num.top());
// printf("\n");
}
else if(op.empty()==true||pri[ch][op.top()]==1){ //符号栈为空 或优先级高于栈顶 则进 符号栈
op.push(ch);
// printf("当前数字是:%d ",op.top());
// printf("\n");
}
else{
while(pri[ch][op.top()]==0){
// printf("当前数字是:%d ",op.top());
// printf("\n");
double tmp1=num.top();
num.pop();
double tmp2=num.top();
num.pop();
int nowOp=op.top();
op.pop();
double nowNum;
if(nowOp==1)
nowNum=tmp2+tmp1;
if(nowOp==2)
nowNum=tmp2-tmp1;
if(nowOp==3)
nowNum=tmp2*tmp1;
if(nowOp==4)
nowNum=tmp2/tmp1;
num.push(nowNum); //运算完后把该步运算结果入数字栈。
}
op.push(ch); //上个while运算完后当前运算符优先级高于栈顶了,故要运算符入栈。。。。。别漏了。。。。
}
if(op.size()==2&&op.top()==0) break; //该循环跳出的条件。
}
printf("%.2lf\n",num.top());
}
return 0;
}