牛客网 校招题 使用栈进行表达式求值
题目描述
#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;
}