题解 | #表达式求值#

表达式求值

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

经典的中缀表达式求值。常用思路,将其转为后缀表达式,边转边求值。
后缀表达式的特点,遇到运算符则将前两个数拿出来运算,便于计算机计算。
这里简单描述一下算法过程:遍历字符串,当读到的是数字时,直接将其压入数字栈。当读到的是运算符时,若符号栈为空,则直接将其压入符号栈;若符号栈非空,则判断符号栈栈顶的运算符优先级,若其优先级大于等于读到的优先级,则将其出栈,并从数字栈弹出两个元素进行该运算,先弹出的为右操作数,后弹出的为左操作数,将结果压入数字栈。重复该操作,直到符号栈栈顶运算符的优先级小于读取的运算符,或符号栈空,则将读取的运算符压入符号栈。重复以上操作直到字符串读完。最后,若符号栈非空,则弹出栈顶元素,并从数字栈弹出两个元素来进行该运算。重复该操作直到符号栈空。弹出数字栈栈顶元素,即得结果。
注:本题中运算符优先级:')'<'+'='-'<'*'。左括号'('较为特殊,读到左括号时直接入栈,读到右括号时一直出栈直到一个左括号出栈。
最初遇到两个坑。一个是在判断运算符出栈条件时,优先级相等的运算符未出栈。这样就造成中缀表达式变为右结合,当算式运算中一直大于等于0时不会出现问题,而当其中出现负数减法时就会出错。如1-2-3,正常情况下左结合结果为-4,而右结合得到的结果时2。另一个坑是在遍历字符串数组时,最开始惯性思维默认了表达式中数字都是个位数,所以循环中每次仅读入1个字符。而提交的用例中有100+100的例子,这样数字栈就变成了先压入1,再压入0...最后改写了读入数据的逻辑,美中不足的是这样做会在循环体内改变循环控制变量i,容易出错。

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 返回表达式的值
     * @param s string字符串 待计算的表达式
     * @return int整型
     */
    int solve(string s) {
        // write code here
        stack<char> sign;
        stack<int> num;
        for(int i = 0;i<s.length();i++){
            if(s[i] >= '0' && s[i] <= '9'){
                int rear = i;
                while((rear+1)<s.length() && s[rear+1] >= '0' && s[rear+1] <= '9'){
                    rear++;
                }
                int n = 0;
                for(int j=rear;j>=i;j--){
                    n += (s[j]-'0')*pow(10,(rear-j));
                }
                i = rear;
                num.push(n);
            }
            else if(sign.size() == 0 || s[i] == '*'|| s[i] == '('){
                sign.push(s[i]);
            }
            else if(s[i] == '+' || s[i] == '-'){
                while(1){
                    if(sign.size() == 0){
                        break;
                    }
                    if(sign.top() == '*'){
                        sign.pop();
                        int n2 = num.top();
                        num.pop();
                        int n1 = num.top();
                        num.pop();
                        num.push(n1*n2);
                    }
                    else if(sign.top() == '+'){
                        sign.pop();
                        int n2 = num.top();
                        num.pop();
                        int n1 = num.top();
                        num.pop();
                        num.push(n1+n2);
                    }
                    else if(sign.top() == '-'){
                        sign.pop();
                        int n2 = num.top();
                        num.pop();
                        int n1 = num.top();
                        num.pop();
                        num.push(n1-n2);
                    }
                    else{
                        break;
                    }
                }
                sign.push(s[i]);
            }
            else if(s[i] == ')'){
                while(1){
                    if(sign.size() == 0){
                        break;
                    }
                    else if(sign.top() == '('){
                        sign.pop();
                        break;
                    }
                    else if(sign.top() == '+'){
                        sign.pop();
                        int n2 = num.top();
                        num.pop();
                        int n1 = num.top();
                        num.pop();
                        num.push(n1+n2);
                    }
                    else if(sign.top() == '-'){
                        sign.pop();
                        int n2 = num.top();
                        num.pop();
                        int n1 = num.top();
                        num.pop();
                        num.push(n1-n2);
                    }
                    else if(sign.top() == '*'){
                        sign.pop();
                        int n2 = num.top();
                        num.pop();
                        int n1 = num.top();
                        num.pop();
                        num.push(n1*n2);
                    }
                }
            }
        }
        while(sign.size()!=0){
            if(sign.top() == '+'){
                sign.pop();
                int n2 = num.top();
                num.pop();
                int n1 = num.top();
                num.pop();
                num.push(n1+n2);
            }
            else if(sign.top() == '-'){
                sign.pop();
                int n2 = num.top();
                num.pop();
                int n1 = num.top();
                num.pop();
                num.push(n1-n2);
            }
            else if(sign.top() == '*'){
                sign.pop();
                int n2 = num.top();
                num.pop();
                int n1 = num.top();
                num.pop();
                num.push(n1*n2);
            }
        }
        return num.top();
    }
};
全部评论

相关推荐

8 收藏 评论
分享
牛客网
牛客企业服务