leetcode-224-Basic Calculator

问题

题目:[leetcode-224]

思路

注意连续数字的情形。
注意只有操作数的情形。

问题:中缀表达式计算
分析:这个前面做过,有几个关键问题。怎么识别元素的问题。还有优先级一定不能变。
先乘除后加减,同类运算符先进栈的优先级高


输入:中缀表达式(字符串),没有空格

处理:
    1.读取表达式
    2.循环:遍历表达式中每一个字符
        2.1.如果是opnd,保存临时结果。
        2.2.如果是optr
            2.2.1.临时结果的操作数入opnd栈。
            2.2.2.判断 当前优先级 和 栈顶优先级关系
                2.2.2.1.大于,入栈
                2.2.2.2.循环:栈顶优先级 < 当前优先级
                    2.2.2.2.1.从optr中弹出optr
                    2.2.2.2.2.从opnd栈中弹出两个操作数
                    2.2.2.2.3.计算,将中间结果入栈
                2.2.2.3.入栈(因为当前操作符早晚是要入栈的)
    3.将最后一个操作数入栈
    4.循环:optr栈不空
        4.1.从optr栈中弹出元素
        4.2.判断是不是#
            4.2.1.是,跳出
            4.2.2.不是,从opnd栈中弹出两个元素进行计算,中间结果入栈。
    5.将opnd栈中结果输出即为最终元素
输出:结果

代码

class Solution {
public:
    int calculate(string s) {
        stack<int> opnd; // 操作数
        stack<char> optr; // 操作符
        int sz = s.size();
        if(1==sz) return string_to_int(s);

        bool flag = true;
        std::string val; // 暂存操作数,为了避免大于1位的数字
        for(int i = 0; i < sz; ++i){
            if(isspace(s[i])) continue;
            else if( isdigit(s[i]) ) val += s[i];
            else{
                if(val != ""){
                    opnd.push(string_to_int(val));
                    val = "";
                }

                if(optr.empty()) optr.push(s[i]); // 栈空
                else if( s[i] == '(' ) optr.push(s[i]); // 左括号
                else if( s[i] == ')'){ // 右括号
                    while(!optr.empty()){
                        char top = optr.top();
                        optr.pop();
                        if(top == '(') break;

                        int right = opnd.top(); opnd.pop();
                        int left = opnd.top(); opnd.pop();
                        int tmp = cal(left, right, top);
                        opnd.push(tmp);
                    }
                }
                else{ // 其他操作符
                    while(!optr.empty()){
                        char top = optr.top();
                        int top_prior = get_prior(top);
                        int cur_prior = get_prior(s[i]);
                        if(cur_prior > top_prior) break;
                        else{
                            int right = opnd.top(); opnd.pop();
                            int left = opnd.top(); opnd.pop();
                            int tmp = cal(left, right, top);
                            opnd.push(tmp);
                            optr.pop();
                        }

                    }
                    optr.push(s[i]); // 当前操作符入栈
                }
            }
        }
        if(val != "") opnd.push(string_to_int(val)); // 为了避免只有操作数没有操作符的情形
        while(!optr.empty()){
            int top = optr.top();
            optr.pop();

            int right = opnd.top(); opnd.pop();
            int left = opnd.top(); opnd.pop();
            int tmp = cal( left, right, top );
            opnd.push(tmp);

        }
        return opnd.top();
    }
private:
    int cal(int left, int right, char op){
        int ans = 0;
        switch(op){
            case '+' : ans = left + right;break;
            case '-' : ans = left - right;break;
            case '*' : ans = left * right;break;
            case '/' : ans = left / right;break;
            default : break;
        }
        return ans;
    }
    int get_prior(char op){
        if( op == '+' || op == '-' ) return 1;
        else if( op == '*' || op =='/' ) return 2;
        else return -1;
    }
    int string_to_int(std::string& s){
        std::stringstream ss;
        ss << s;
        int val;
        ss >> val;
        return val;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值