题目地址:简单计算器
题目思路:给出的是中缀表达式,先转化成后缀表达式(计算这类东西常用用的套路),计算后缀表达式,使用队列和栈。
找了大半天的bug,找到原因了,故记录一下踩到的坑,希望以后不会再犯了。
- 一定要进行queue和stack(先作为符号栈,然后作为结果存放栈)是否为空的判断,然后继续进行操作
- 在转换为后缀表达式时,使用while循环会比for循环更加简明,这种情况还是继续用while循环比较好
- 在进行运算符转变为后缀表达式时,op要与操作符栈的栈顶操作符进行比较,高于时直接压入栈,低于或等于时要把操作符栈的操作符弹出到后缀表达式中直到op大于操作符栈顶元素
#include <bits/stdc++.h>
using namespace std;
struct node {
double num;
char op;
bool flag;
};
string str;
stack<node> s;//操作符栈
queue<node> q;//后缀表达式序列
map<char,int> ope;
void change(){
double num;
node temp;
int i=0;
while(i<str.length()){
if(str[i]>='0'&& str[i]<='9'){//数字则存入q中
temp.flag=true;
temp.num=str[i++]-'0';
while(i<str.length()&&str[i]>='0'&&str[i]<='9'){
temp.num=temp.num*10+(str[i]-'0');
i++;
}
q.push(temp);
} else{
temp.flag=false;//符号
while(!s.empty()&&ope[str[i]]<=ope[s.top().op]){
q.push(s.top());
s.pop();
}
temp.op=str[i];
s.push(temp);
i++;
}
}
while(!s.empty()){
q.push(s.top());
s.pop();
}
}
double cal(){
double temp1,temp2;
node cur,temp;
while(!q.empty()){
cur=q.front();
q.pop();
if(cur.flag==true)//数字
s.push(cur);//s存放结果
else{
temp2=s.top().num;
s.pop();
temp1=s.top().num;
s.pop();
temp.flag=true;
if(cur.op=='+') temp.num=temp1+temp2;
else if(cur.op=='-') temp.num=temp1-temp2;
else if(cur.op=='*') temp.num=temp1*temp2;
else temp.num=temp1/temp2;
s.push(temp);
}
}
return s.top().num;
}
int main(){
ope['+']=ope['-']=0;
ope['*']=ope['/']=1;
while(getline(cin,str),str!="0"){
for(string::iterator it=str.begin();it!=str.end();it++){
if(*it==' ')str.erase(it);
}
while(!s.empty()) s.pop();
change();
double res= cal();
printf("%.2f\n",res);
}
return 0;
}