LeetCode——计算表达式

224. 基本计算器 - 力扣(LeetCode)

【进阶补充】双栈解决通用「表达式计算」问题

class Solution {
public:
    void replace(string &s)
    {
        int pos = s.find(" ");
        while(pos != -1)
        {
            s.replace(pos, 1, "");
            pos = s.find(" ");
        }
    }
    int calculate(string s) {
        stack<int> nums;
        nums.push(0);
        replace(s);
        stack<char> ops;
        int n = s.size();
        for(int i = 0; i < n; i ++ )
        {
            char c = s[i];
            if(c == '(') ops.push(c);
            else if(c == ')')
            {
                while(!ops.empty())
                {
                    char op = ops.top();
                    if(op == '(')
                    {
                        ops.pop();
                        break;
                    }
                    else calc(nums, ops);
                }
            }
            else
            {
                if(isdigit(c))
                {
                    int cur_num = 0;
                    int j = i;
                    //找数
                    while(j < n && isdigit(s[j]))
                        cur_num = cur_num * 10 + (s[j ++] - '0');
                    nums.push(cur_num);
                    i = j - 1;
                }  
                else
                {
                    if(i > 0 && s[i - 1] == '(')
                        nums.push(0);
                    while(!ops.empty() && ops.top() != '(')
                        calc(nums, ops);
                    ops.push(c);
                }
            }
        }
        while(!ops. empty())
            calc(nums, ops);
        return nums.top();
    }
    void calc(stack<int> &nums, stack<char> &ops)
    {
        if(nums.size() < 2 || ops.empty()) return;

        int b = nums.top(); nums.pop();
        int a = nums.top(); nums.pop();
        char op = ops.top(); ops.pop();
        nums.push(op == '+' ? a + b : a - b);
    }
};

227. 基本计算器 II 题解 - 力扣(LeetCode)

【宫水三叶】使用「双栈」解决「究极表达式计算」问题 - 基本计算器 II - 力扣(LeetCode)

class Solution {
public:
    void replace(string &s)
    {
        int k = s.find(" ");
        while(k != -1)
        {
            s.replace(k, 1, "");
            k = s.find(" ");
        }
    }
    unordered_map<char, int> ops_pri = {
        {'+', 1},
        {'-', 1},
        {'*', 2},
        {'/', 2},
        {'%', 2},
        {'^', 3}
    };//定义优先级
    stack<int> ops;
    stack<long long> nums;
    int calculate(string s) {
        nums.push(0);//防止第一个数为负
        replace(s);//删除所有空格
        int n = s.size();
        for(int i = 0; i < n; i ++ )
        {
            char c = s[i];
            if(c == '(')//直接放进去
                ops.push(c);
            else if(c == ')')//计算到(
            {
                while(!ops.empty())
                {
                    char op = ops.top();
                    if(op == '(')
                    {
                        ops.pop();
                        break;
                    }
                    else calc();
                }
            }
            else
            {
                if(isdigit(c))//读取数字
                {
                    int cur_num = 0;
                    int j = i;
                    while(j < n && isdigit(s[j]))
                        cur_num = cur_num * 10 + (s[j ++] - '0');
                    nums.push(cur_num);
                    i = j - 1;
                }
                else
                {
                    if(i > 0 && s[i - 1] == '(')
                        nums.push(0);
                    while(!ops.empty() && ops.top() != '(' && ops_pri[ops.top()] >= ops_pri[c])//站内运算符优先级高
                        calc();
                    ops.push(c);
                }
            }
        }
        while(!ops.empty())
            calc();
        return nums.top();
    }
    void calc()
    {
        long long b = nums.top(); nums.pop();
        long long a = nums.top(); nums.pop();
        char op = ops.top(); ops.pop();
        long long res;
        switch(op)
        {
            case '+': res = a + b; break;
            case '-': res = a - b; break;
            case '*': res = a * b; break;
            case '/': res = a / b; break;
            case '%': res = a % b; break;
            case '^': res = a ^ b; break;
        }
        nums.push(res);
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值