1918:简单计算器
题目大意
读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
注意
1、很经典的栈操作,主要是getNext()得到下一个运算符/运算数的函数难写。要考虑字符串开头或结尾。这次是标记了一个结束标志,比较方便。
2、判断是否结束运算的条件要注意。
#include<stdio.h>
#include<stack>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
stack<double> num;//操作数栈
stack<int> opr;//操作符栈
string str;//操作式
int len;//操作式长度
bool ifend;//是否到字符串结尾
int priority[][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
};
//i:字符串序号;v:操作符优先级/操作数;ifop:是否为操作符
void getNext(int &i,int &v,bool &ifop){
v=0;//清空之前的数值
//如果是字符串开头
if(i==0&&ifend!=true){
opr.push(0);
while(str[i]!=' '&&i!=len){
v*=10;
v+=str[i]-'0';
i++;
}
ifop=false;
return;
}
//如果是字符串结尾
if(ifend){
ifop=true;
v=0;
return;
}
if(str[i]==' ')i++;//跳过空格
while(str[i]!=' '){
//如果是操作数
if(str[i]>='0'&&str[i]<='9'){
ifop=false;
while(str[i]!=' '&&i<len){
v*=10;
v+=str[i]-'0';
i++;
}
return;
}
//如果是操作符
else{
ifop=true;
switch(str[i]){
case '+':v=1;break;
case '-':v=2;break;
case '*':v=3;break;
case '/':v=4;break;
}
i++;
return;
}
}
}
int main(void){
while(getline(cin,str)){
if(str=="0")break;
len=str.length();
ifend=false;
//清空栈
while(!opr.empty())opr.pop();
while(!num.empty())num.pop();
int idx=0,val;
bool ifop=false;
while(idx<len){
getNext(idx,val,ifop);//得到当前操作符/操作数
//如果是操作符
if(ifop==true){
//如果当前操作符优先级高于栈顶操作符,则入栈
if(priority[val][opr.top()]==1)opr.push(val);
//如果当前操作符优先级低于栈顶操作符,则num弹出两个数计算
else{
while(priority[val][opr.top()]==0){
double a,b,tmp;
a=num.top();num.pop();
b=num.top();num.pop();
switch(opr.top()){
case 1:tmp=b+a;break;
case 2:tmp=b-a;break;
case 3:tmp=b*a;break;
case 4:tmp=b/a;break;
}
num.push(tmp);
opr.pop();
}
opr.push(val);
}
}
else num.push(val);
if(opr.size()==2&&num.empty()!=true&&ifend==true){
printf("%.2lf\n",num.top());
break;
}
if(idx==len){idx--;ifend=true;}
}
}
}