[编程题]简单计算器

关键词:栈,计算器
试题链接:
简单计算器
问题描述:
[编程题]简单计算器
思路:
参考《算法笔记》思路,完成计算总共需要两步。
①中缀表达式转换为后缀表达式。
②计算后缀表达式。
[编程题]简单计算器
[编程题]简单计算器

解决方案:
这个是按照算法笔记上面的写的,还没有设置输出小数点后两位,放在本地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确实慢就是了。
[编程题]简单计算器

上一篇:TCP/UDP/socket


下一篇:文件的上传和下载