[栈]leetcode224:基本计算器(hard)

leetcode||acwing刷题 同时被 2 个专栏收录
415 篇文章 16 订阅
6 篇文章 1 订阅

题目:
在这里插入图片描述


题解:

  • 利用中缀表达式直接求值的运算法则来做,使用两个栈:符号栈和数字栈。当遍历到的字符的优先级大于>符号栈的栈顶元素的优先级时,才入栈;否则就弹出操作符,以及数字栈的两个元素,进行运算,直到符号栈的栈顶元素优先级 小于<当前操作符时,才将当前操作符入栈。
  • 当所有操作符处理完毕(即操作符栈为空时),数字栈中剩下的唯一元素为最终表达式的值。

代码如下:

class Solution {
public:
    // 预处理空格和()里面出现首个数字为负数的情况,将"(-"替换为"(0-"
    void replace(string &s)
    {
        int pos=s.find(" ");
        while(pos!=-1){
            s.replace(pos,1,"");
            pos=s.find(" ");
        }
        pos=s.find("(-");
        while(pos!=-1){
            s.replace(pos,2,"(0-");
            pos=s.find("(-");
        }
    }

    // 中缀表达式直接求值:双栈法,符号栈和数字栈
    int calculate(string s) {
        stack<int> nums;
        // 为了防止第一个数为负数,减少边界的判断,所以加0就ok了
        nums.push(0);
        // 预处理字符串
        replace(s);
        stack<char> ops;
        int n=s.size();
        for(int i=0;i<n;++i)
        {
            if(s[i]=='(')ops.push(s[i]);
            // 计算到最近一个左括号为止
            else if(s[i]==')')
            {
                // 计算到最近一个左括号为止
                while(!ops.empty()) {
                    char op = ops.top();
                    if(op != '(')
                        calc(nums, ops);
                    else {
                        ops.pop();
                        break;
                    }
                }
            }
            else if(isdigit(s[i]))
            {
                // 计算连续的数字,并存入nums
                int j=i,x=0;
                while(j<n&&isdigit(s[j]))
                    x=x*10+(s[j++]-'0');
                i=j-1;
                nums.push(x);
            }
            // 处理 + - ,每加入一个运算符,都要把栈内可以算的先算了
            else
            {
                while(!ops.empty() && ops.top() != '(')
                    calc(nums, ops);
                ops.push(s[i]);
            }
        }
        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);
    }
};
  • 0
    点赞
  • 0
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 撸撸猫 设计师:马嘣嘣 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值