[栈]面试题 16.26. 计算器(medium)

程序员面试金典 专栏收录该内容
6 篇文章 0 订阅

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


题解:


代码如下:

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("(-");
        }
    }

    // 运算符优先级
    map<char,int> dict={{'-',1},{'+',1},{'/',2},{'*',2}};

    // 题解:双栈法,中缀表示式直接求值
    int calculate(string s) {
        replace(s);
        stack<int> nums;
        // 防止第一个数为负数,减少边界的判断
        nums.push(0);
        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.size()){
                    if(ops.top()!='(')calc(nums,ops);
                    else {ops.pop();break;}
                }
            }
            // 处理从i开始的连续数字
            else if(isdigit(s[i])){
                int j=i,x=0;
                while(j<n&&isdigit(s[j]))
                    x=x*10+(s[j++]-'0');
                i=j-1;// 因为退出if语句后再 for循环中 i++ 还是要执行的,所以i要后退一位
                nums.push(x);
            }
            // 处理 + - * /
            else{
                // 当前操作符的优先级 <= 栈顶操作符优先级时,弹栈进行运算;否则入栈
                while(!ops.empty()&&ops.top()!='('){
                    if(dict[s[i]]<=dict[ops.top()])calc(nums,ops);
                    else break;
                }
                ops.push(s[i]);
            }
        }
        while(!ops.empty()&&ops.top()!='(')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();
        switch(op)
        {
            case '+':nums.push(a+b);break;
            case '-':nums.push(a-b);break;
            case '*':nums.push(a*b);break;
            case '/':nums.push(a/b);break;
        }
    }
};
  • 1
    点赞
  • 1
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

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

抵扣说明:

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

余额充值