#include<cstdio>
#include<string>
#include<map>
#include<queue>
#include<stack>
#include<iostream>
#include<algorithm>
using namespace std;
struct node
{
double num;
char op;
bool flag;
}; //错误点: 建立了一个真的node,以下的类型定义都是node,导致了错误
map<char, int> op; //存放操作数优先级
stack<node> s; //操作符栈
queue<node> q; //后缀表达式序列
string str;
void change() //中缀表达式转后缀表达式
{
int i = 0;
while(i < str.length())
{
node temp, cur;
//区分操作数和操作符
if(str[i] >= '0' && str[i] <= '9') //num 接收到整数,并存入node,压入栈
{
temp.num = str[i++] - '0';
while(str[i] >= '0' && str[i] <= '9' && i < str.length())
{
temp.num = temp.num * 10 + (str[i] - '0');
i++;
}
temp.flag = true;
q.push(temp);
}
else //op 和栈顶元素比较优先级,如果高,则入栈;如果<=则将栈顶元素弹出,op入站,要循环直到栈空或op优先级大于栈顶
{
temp.flag = false;
temp.op = str[i];
if(temp.op=='(')
{
s.push(temp);
i++;
}
else if(temp.op==')') //右括号是不入栈的
{
while(!s.empty()&&s.top().op!='(')
{
q.push(s.top());
s.pop();
}
if(!s.empty()&&s.top().op=='(')
s.pop();
i++;
}
else
{
while(!s.empty()&&op[str[i]] <= op[s.top().op])
//错误点1:op[s.top()]
//错误点2:忘了判断s是否空
//错误点3:判断s非空需要放在另一个条件前面
//错误点4:要循环啊!!!!
{
q.push(s.top());
s.pop();
}
s.push(temp); //如果当前op不是括号,那不管加减乘除都要入栈,区别在于和栈顶元素比较后的操作
i++;
}
}
}
while(!s.empty())
{
q.push(s.top());
s.pop();
}
}
double cal()
{
node temp,cur,c1;
double n1,n2;
while(!q.empty())
{
cur=q.front();
q.pop();
if(cur.flag) //如果是操作数
s.push(cur);
else //如果是op
{
//从栈中弹出两个操作数
//cout<<cur.op<<" ";
n2=s.top().num;
s.pop();
n1=s.top().num;
s.pop();
//cout<<n1<<" "<<n2<<" "<<cur.op<<endl;
if(cur.op=='+') temp.num=n1+n2;
else if(cur.op=='-') temp.num=n1-n2;
else if(cur.op=='*') temp.num=n1*n2;
else if(cur.op=='/') temp.num=n1/n2;
temp.flag=true;
s.push(temp);
}
}
return s.top().num;
}
int main()
{
op['+'] = op['-'] = 1;
op['*'] = op['/'] = 2;
while(getline(cin, str), str != "0")
{
//去掉空格
for(string::iterator it = str.end(); it != str.begin(); it--)
if(*it == ' ') //错误点:" " 又是双引号的错误
str.erase(it);
//cout<<str<<endl;
change();
printf("%.2f\n", cal());
//错误点:每次都要清空一下栈和队列啊少年!!!
while(!s.empty())
s.pop();
while(!q.empty())
q.pop();
}
return 0;
}
// 带括号的样例:(56-20)/(4+2)
//不带括号的样例:30 / 90 - 26 + 97 - 5 - 6 - 13 / 88 * 6 + 51 / 29 + 79 * 87 + 57 * 92
//12178.21
简易计算器_中缀表达式转后缀表达式 (STL应用)&&(包含英文括号,有错误请打我)
最新推荐文章于 2022-01-10 17:16:25 发布