AcWing 3302. 表达式求值

题目来源:

AcWing - 算法基础课


题目内容:

给定一个表达式,其中运算符仅包含 +,-,*,/(加 减 乘 整除),可能包含括号,请你求出表达式的最终值。

注意:

  • 数据保证给定的表达式合法。
  • 题目保证符号 - 只作为减号出现,不会作为负号出现,例如,-1+2,(2+2)*(-(1+1)+2) 之类表达式均不会出现。
  • 题目保证表达式中所有数字均为正整数。
  • 题目保证表达式在中间计算过程以及结果中,均不超过 231−1。
  • 题目中的整除是指向 0
  • 取整,也就是说对于大于 0 的结果向下取整,例如 5/3=1,对于小于 0 的结果向上取整,例如 5/(1−4)=−1
  • C++和Java中的整除默认是向零取整;Python中的整除//默认向下取整,因此Python的eval()函数中的整除也是向下取整,在本题中不能直接使用。

输入格式

共一行,为给定表达式。

输出格式

共一行,为表达式的结果。

数据范围

表达式的长度不超过 105。

输入样例:
(2+2)*(1+1)
输出样例:
8

    思路分析:

    • 双栈:一个操作数栈,一个运算符栈
    • 栈顶运算符和即将入栈的运算符的优先级比较

            (1)如果栈顶是+,即将入栈的是+,栈顶优先级高,需要先计算,再入栈;

            (2)如果栈顶是+,即将入栈的是*,栈顶优先级低,直接入栈;

            (3)如果栈顶是*,即将入栈的是+,栈顶优先级高,需要先计算,再入栈;

            (4)如果栈顶是*,即将入栈的是*,栈顶优先级高,需要先计算,再入栈;


    代码实现:

    #include <iostream>
    #include <stack>
    #include <string>
    #include <unordered_map>
    using namespace std;
    
    stack<int> num;
    stack<char> op;
    
    //优先级表
    unordered_map<char, int> h{ {'+', 1}, {'-', 1}, {'*',2}, {'/', 2} };
    
    
    void eval()//求值
    {
        int a = num.top();//第二个操作数
        num.pop();
    
        int b = num.top();//第一个操作数
        num.pop();
    
        char p = op.top();//运算符
        op.pop();
    
        int r = 0;//结果 
    
        //计算结果
        if (p == '+') r = b + a;
        if (p == '-') r = b - a;
        if (p == '*') r = b * a;
        if (p == '/') r = b / a;
    
        num.push(r);//结果入栈
    }
    
    int main()
    {
        string s;//读入表达式
        cin >> s;
    
        for (int i = 0; i < s.size(); i++)
        {
            if (isdigit(s[i]))//数字入栈
            {
                int x = 0, j = i;//计算数字
                while (j < s.size() && isdigit(s[j]))
                {
                    x = x * 10 + s[j] - '0';
                    j++;
                }
                num.push(x);//数字入栈
                i = j - 1;
            }
            //左括号无优先级,直接入栈
            else if (s[i] == '(')//左括号入栈
            {
                op.push(s[i]);
            }
            //括号特殊,遇到左括号直接入栈,遇到右括号计算括号里面的
            else if (s[i] == ')')//右括号
            {
                while(op.top() != '(')//一直计算到左括号
                    eval();
                op.pop();//左括号出栈
            }
            else
            {
                while (op.size() && h[op.top()] >= h[s[i]])//待入栈运算符优先级低,则先计算
                    eval();
                op.push(s[i]);//操作符入栈
            }
        }
        while (op.size()) eval();//剩余的进行计算
        cout << num.top() << endl;//输出结果
        return 0;
    }
    

    题目心得:

    1. 还是那种情况照着敲一遍,结果就是运行不出来,你说你闹心不

    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值