题解 | 表达式求值

表达式求值

https://www.nowcoder.com/practice/c215ba61c8b1443b996351df929dc4d4

个人觉得写这道题的关键在于理解数学公式计算时的思维过程,

首先就算是看运算符的优先级,我使用了哈希表来实现,*的优先级为2,+法于-法为1.

然后就得弄清楚什么时候计算:

1.有括号时,先算括号中的,

1.可以从输入的第一个左括号算起,当遇到右括号时计算出括号中的总值.

2.如果不知道具体该怎么样运算,可以先用一个calcul函数替代(只要知道这个函数是将结果存储在num.top上即可),等后续再 补充.

2.当一个运算符的下一个运算符优先级不大于他自身时(可以将这个运算符和他旁边的两个数算出),这又要分2种情况:

1.这个运算符的下一个运算符不大于他(对应solve函数中的if (map[op.top()] >= map[i])

这种情况下直接在solve函数中算出即可,如果下一个的优先级大于他,则先存入符号栈中,等到后续再统一计算。

2.这个运算符的上一个不大于他(对于calcul中的if (map[c] >= map[op.top()])的else块

这种情况负责处理上一种情况剩下的数据,会将优先级高的符号消去,保留同级的符号.最后实现运算.

由上述分析,得:

class Solution {
  public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 返回表达式的值
     * @param s string字符串 待计算的表达式
     * @return int整型
     */
    int select(int x1, int x2, char op) {
        switch (op) {
            case '+':
                return x1 + x2;
                break;
            case '-':
                return x1 - x2;
                break;
            case '*':
                return x1 * x2;
                break;

        }
        return 0;
    }//计算.


    void calcul(stack<int>& num, stack<char>& op) {
        unordered_map<char, int> map = {
            {'+', 1},
            {'-', 1},
            {'*', 2}
        };
        if (op.empty()) return ;
        if (num.size() < 2) return;
        char c = op.top();




        if (op.size() > 1) {
            op.pop();
            if (op.top() != '(') {
                if (map[c] >= map[op.top()]) {
                    int x2 = num.top();
                    num.pop();
                    int x1 = num.top();
                    num.pop();
                    num.push(select(x1, x2, c));
                } else {

                    int x2 = num.top();
                    num.pop();
                    int x1 = num.top();
                    num.pop();
                    int x3 = num.top();
                    num.pop();
                    num.push(select(x3, x1, op.top()));
                    op.pop();
                    op.push(c);
                    num.push(x2);

                }//如果进入else代表op.top()一定是'*',所以先只计算优先级大的乘法,将优先级小的再放回去.
            } else {
                int x2 = num.top();
                num.pop();
                int x1 = num.top();
                num.pop();
                num.push(select(x1, x2, c));
            }//如果去掉一个符号是左括号,代表只有1个运算符号

        }






        else {
            int x2 = num.top();
            num.pop();
            int x1 = num.top();
            num.pop();
            num.push(select(x1, x2, c));
            op.pop();
        }


    }
    int solve(string s) {
        unordered_map<char, int> map = {
            {'+', 1},
            {'-', 1},
            {'*', 2}
        };
        stack<int> num;
        stack<char> op;
        int now = 0;
        for (char i : s) {
            if (i >= '0' && i <= '9') {
                now = now * 10 + i - '0';

            } else {
                if (now != 0) {
                    num.push(now);
                    now = 0;
                }

                //处理符号
                if (i == '(') {
                    op.push(i);
                } else if (i == ')') {
                    while (op.top() != '(') {

                        calcul(num, op); //calcul中要记得消去左括号

                    }
                    op.pop();
                } else {



                    if (op.empty() || num.size() < 2) {
                        op.push(i);
                    } else {

                        if (map[op.top()] >= map[i]) {
                            int x2 = num.top();
                            num.pop();
                            int x1 = num.top();
                            num.pop();
                            num.push(select(x1,x2,op.top()));
                            op.pop();
                            op.push(i);

                        } else {
                            op.push(i);
                        }

                    }

                }

            }
        }

        if (now != 0) {
            num.push(now);
            now = 0;
        }


        while (!op.empty()) {

            calcul(num, op);

        }
        return num.top();

    }
};

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务