牛客網 校招題 使用棧進行表達式求值
題目描述
#include <iostream>
#include <queue>
#include <stdlib.h>
#include <stdio.h>
#include <map>
#include <string>
#include <cstdlib>
#include <stack>
#include <vector>
#include <math.h>
#include <algorithm>
#include <typeinfo>
#include <cstring>
using namespace std;
std::map<char, int> prio;
int fpow(int base,int exp){
int ans=1;
while(exp){
if(exp&1) ans*=base;
base*=base;
exp>>=1;
}
return ans;
}
double D2S(string a){
double ans=0.0;
int len=a.length();
for(int i=len-1;i>=0;i--){
ans+=(double)(a[i]-'0')*(double)fpow(10,len-1-i);
}
return ans;
}
double calc(double a,double b,char op){
if(op=='+')
return a+b;
else if(op=='-')
return a-b;
else if(op=='/')
return a/b;
else if(op=='*')
return a*b;
return 0.0;
}
int main(int argc, char const *argv[])
{
char str[500];
prio['+']=prio['-']=1;
prio['*']=prio['/']=2;
while(gets(str)&&str[0]!='0'){
stack<char> opcode;
stack<double> oprand;
int len=strlen(str);
for(int i=0;i<len;i++){
if(str[i]=='*'||str[i]=='/'||str[i]=='+'||str[i]=='-'){
//opcode.push(str[i]);
if(!opcode.empty()){
//此處必須使用while循環將此時棧中所有可以先進行計算的有序對計算出結果
//不能使用if,否則只能計算出棧頂一對的值,而此時棧中可以優先計算的對
//將會在後續進行操作的時候失去從左到右計算的特性,而從左到右計算是中綴表達式的本質要求
while(!opcode.empty()&&prio[str[i]]<=prio[opcode.top()]){
//先計算的前提條件是當前運算符的優先級比棧中的優先級低
//則此時計算棧中的序對不會再對後續的表達式造成影響
double b=oprand.top();oprand.pop();
double a=oprand.top();oprand.pop();
//要注意ab的順序
char t=opcode.top();
opcode.pop();
//printf("%lf %c %lf\n", a,t,b);
oprand.push(calc(a,b,t));
}
opcode.push(str[i]);
}
else{
opcode.push(str[i]);
}
}
string tmp="";
while(str[i]<='9'&&str[i]>='0'&&i<len){
tmp+=str[i];i++;
}
if(tmp!=""){
oprand.push(D2S(tmp));
//cout<<oprand.top()<<endl;
}
}
//到這裏棧中還會剩下最後一對,不要忘記
while(!opcode.empty()){
double a=oprand.top();oprand.pop();
double b=oprand.top();oprand.pop();
double t=calc(b,a,opcode.top());
//printf("%lf %c %lf\n", b,opcode.top(),a);
oprand.push(t);
opcode.pop();
}
printf("%.2lf\n", oprand.top());
}
return 0;
}