关键词:栈,计算器
试题链接:
简单计算器
问题描述:
思路:
参考《算法笔记》思路,完成计算总共需要两步。
①中缀表达式转换为后缀表达式。
②计算后缀表达式。
解决方案:
这个是按照算法笔记上面的写的,还没有设置输出小数点后两位,放在本地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确实慢就是了。