Leetcode 224基本计算器

Leetcode 224基本计算器

  • 题目简述:请实现一个简易计算器,计算一个算数表达式的值。表达式中仅包含左括号(、右括号)、加号+、减号-、非负整数 和空格。

  • 输入:“1 + 1” 输出:2

    输入:" 2-1 + 2 " 输出:3

    输入:"(1+(4+5+2)-3)+(6+8)" 输出:23

  • 思路:双栈法:利用两个栈一个记录数字,一个记录操作符,然后从前往后扫描表达式

    • 如果遇到左括号(+-、直接加入操作符栈中
    • 如果遇到数字,则判断操作符栈的栈顶元素,如果该元素是+或者-,就进行相应操作并在操作符栈中弹出完成的操作符,同时更新数字栈顶元素。如果该元素是(,就继续扫描下一个字符
    • 如果遇到),此时操作符栈顶一定是(,将其弹出。然后根据新的操作符栈顶元素,对数字栈顶的两个元素进行相应计算操作。

    代码逻辑先写第三步再写第二步,思考时要按照表达式顺序先看数字再看右括号正常考虑,时间复杂度O(n)

class Solution {
public:
    void calc(stack<int> &nums, stack<char> &op) {
        int n2 = nums.top(); nums.pop();
        int n1 = nums.top(); nums.pop();
        char c = op.top(); op.pop();
        if (c == '+') nums.push(n1 + n2);
        else nums.push(n1 - n2);
    }

    int calculate(string s) {
        stack<int> nums;
        stack<char> op;
        for(int i = 0; i < s.size(); i++)
        {
            //遇到空格、+-号和左括号
            if(s[i] == ' ') continue;
            if(s[i] == '+' || s[i] == '-' || s[i] == '(') op.push(s[i]);
            else if(s[i] == ')')//遇到右括号
            {
                op.pop();//此时栈顶一定是左括号,因为+-号已经在数字计算时弹出了
                if(op.size() && (op.top() == '-' || op.top() == '+'))
                    calc(nums, op);
            }
            else//遇到数字
            {
                int j = i, n = 0;
                //处理多位数,isdigit函数用于判断参数是否是十进制数
                while(j < s.size() && isdigit(s[j]))
                {
                    n = n * 10 + (s[j] - '0');
                    j++;
                }
                nums.push(n);
                //处理多位数等价写法
                //while (j < s.size() && isdigit(s[j])) j ++ ;
                //num.push(atoi(s.substr(i, j - i).c_str()));
                i = j - 1;//恢复原来i的下标位置
                if(op.size() && (op.top() == '-' || op.top() == '+'))
                    calc(nums, op);
            }
        }
        return nums.top();
    }
};
  • 思路二:单栈法:利用变量res记录当前表达式结算结果,sign记录遇到的运算符,再用栈存储这两个变量
    • 当遇到左括号时,相当于遇到了一个新子表达式,将两个变量压栈并进行重新赋值
    • 当遇到数字时就对数字进行字符转数字处理
    • 当遇到加号减号符号时,记录当前结果和运算符,将1-2转换成(+1) + (-2)
    • 当遇到右括号时,相当于子表达式结束,将当前的子表达式结果累加到栈中的结果上
class Solution {
public:
    int calculate(string s) {
        int sign = 1, res = 0;
        int num = 0;
        stack<int> stk;

        for(int i = 0; i < s.size(); i++)
        {
            if(isspace(s[i])) continue;
            if(s[i] == '(')
            {
                stk.push(res);
                stk.push(sign);
                res = 0;
                sign = 1;
            }
            else if(isdigit(s[i]))
                num = num * 10 + (s[i] - '0');
            else if(s[i] == '+' || s[i] == '-')
            {
                res += sign * num;
                num = 0;
                sign = (s[i] == '+' ? 1 : -1);
            }
            else if(s[i] == ')')
            {
                res += sign * num;
                res *= stk.top();
                stk.pop();
                res += stk.top();
                stk.pop();
                num = 0;
            }
        }
        return res + sign * num;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值