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;}
}
}
}