題目描述
讀入一個只包含 +, -, *, / 的非負整數計算表達式,計算該表達式的值。
輸入描述:
測試輸入包含若干測試用例,每個測試用例佔一行,每行不超過200個字符,整數和運算符之間用一個空格分隔。沒有非法表達式。當一行中只有0時輸入結束,相應的結果不要輸出。
輸出描述:
對每個測試用例輸出1行,即該表達式的值,精確到小數點後2位。
示例1
輸入
1 + 2 4 + 2 * 5 - 7 / 11 0
輸出
3.00 13.36
題解:
參考算法筆記上的題解
AC代碼:
#include <iostream>
#include <stdio.h>
#include<map>
#include<string>
#include<stack>
#include<queue> //存放後綴表達式
using namespace std;
struct Node{
char op;
double num;
bool flag; //flag=true 證明是數字
};
map<char,int> op;
queue<Node> q;
stack<Node> s;
string str;
//中綴表達式轉換成後綴表達式
void Change(){
Node t;
double tmp; //一開始這裏的double變量定義成了int
char c;
for(int i=0;i<str.length();){
if(str[i]>='0' && str[i]<='9'){
tmp=str[i++]-'0';
while(str[i]>='0' && str[i]<='9' && i<str.length()){
tmp=tmp*10+str[i++]-'0';
}
t.flag= true;
t.num=tmp;
q.push(t);
}
else{
//操作符
c=str[i];
while( !s.empty() && op[c]<=op[s.top().op]){
q.push(s.top());
s.pop();
}
t.flag= false;
t.op=c;
s.push(t); //這個操作符是要入棧的
i++;
}
}
while(!s.empty()){
q.push(s.top());
s.pop();
}
}
//計算後綴表達式的值
double Cal(){
while(!q.empty()){
Node tp=q.front();
q.pop();
double num1,num2;
if(tp.flag){
s.push(tp); //利用棧計算後綴表達式的值
}
else{
Node res;
num2=s.top().num;
s.pop();
num1=s.top().num;
s.pop();
if(tp.op=='+') res.num=num1+num2;
else if(tp.op=='-') res.num=num1-num2;
else if(tp.op=='*') res.num=num1*num2;
else if(tp.op=='/') res.num=num1/num2;
res.flag=true;
s.push(res);
}
}
return s.top().num;
}
int main(){
//沒有括號的加減乘除 整數運算
op['+']=op['-']=1;
op['*']=op['/']=2;
while( getline(cin,str) && str!="0"){
while(!q.empty()) q.pop();
while(!s.empty()) s.pop();
//去除空格
for(string::iterator it=str.begin();it!=str.end();it++){
if(*it==' ')
str.erase(it);
}
Change();
//注意輸出格式
printf("%.2f\n",Cal());
// cout<<setprecision(2)<<Cal()<<endl;
}
return 0;
}