关键词:栈,计算器
试题链接:
简单计算器
问题描述:
思路:
参考《算法笔记》思路,完成计算总共需要两步。
①中缀表达式转换为后缀表达式。
②计算后缀表达式。
解决方案:
这个是按照算法笔记上面的写的,还没有设置输出小数点后两位,放在本地vs跑可以跑通。
但是放在牛客网上跑就出现段错误,讲真不知道为什么,心情复杂,我恨段错误。
#include<iostream>
#include<string>
#include<stack>
#include<queue>
#include<map>
using namespace std;
struct node {
double num;
char op;
bool flag; //true代表数字,false代表操作符
};
string s;
stack<node> sk; //操作符栈
queue<node> q; //后缀队列
map<char, int> op; //操作符优先级
//中缀表达式转后缀表达式
void change() {
node tmp;
for (int i = 0; i < s.length();) {
if (s[i] <= '9' && s[i] >= '0') { //第一个是数字直接放进后缀队列
tmp.flag = true;
tmp.num = s[i++] - '0';
while (i < s.length() && s[i] <= '9' && s[i] >= '0')//向后继续扫描更新数字
{
tmp.num = tmp.num * 10 + s[i++] - '0';
}
q.push(tmp); //放进后缀队列
}
else { //扫描到的是操作符
tmp.flag = false;
while (!sk.empty() && op[s[i]] <= op[sk.top().op]) { //比较当前操作符与栈顶操作符的优先级
q.push(sk.top());
sk.pop();
}
tmp.op = s[i++];
sk.push(tmp); //将该操作符放进操作符栈中
}
}
//遍历完毕后,如果操作符栈中还有操作符,就放进后缀队列中
while (!sk.empty()) {
q.push(sk.top());
sk.pop();
}
}
//计算后缀表达式
double calculate() {
double tmp1, tmp2;
node cur, tmp;
while (!q.empty()) {
cur = q.front(); //记录队首元素
q.pop();
if (cur.flag == true) { //数字直接压入栈
sk.push(cur);
}
else { //操作符的话弹出两个数字计算
tmp2 = sk.top().num;
sk.pop();
tmp1 = sk.top().num;
sk.pop();
if (cur.op == '+')tmp.num = tmp1 + tmp2;
else if (cur.op == '-')tmp.num = tmp1 - tmp2;
else if (cur.op == '*')tmp.num = tmp1 * tmp2;
else tmp.num = tmp1 / tmp2;
tmp.flag = true;
sk.push(tmp);//操作数入栈
}
}
return sk.top().num; //最后栈顶元素就是计算出的结果
}
int main() {
//运算符优先级设置
op['+'] = op['-'] = 1;
op['*'] = op['/'] = 2;
while (getline(cin, s), s != "0") {
int index=0;
while ((index = s.find(' ', index)) != string::npos)
{
s.erase(index, 1);
}
while (!sk.empty())sk.pop(); //初始化栈
change(); //转换为后缀表达式
cout << calculate() << endl;
}
return 0;
}
然后跑出来的样例结果是没有错的…
自己又试了几个样例…计算上也没有毛病。
还有看到下面一些解答:
这是用python3实现的情况,就离谱。
while True:
try:
a=input()
if a!="0":
print("{0:.2f}".format(eval(a)))
except:
break
但py确实慢就是了。