Leetcode 224. Basic Calculator (计算器递归好题)

  1. Basic Calculator
    Hard
    Given a string s representing a valid expression, implement a basic calculator to evaluate it, and return the result of the evaluation.

Note: You are not allowed to use any built-in function which evaluates strings as mathematical expressions, such as eval().

Example 1:

Input: s = “1 + 1”
Output: 2
Example 2:

Input: s = " 2-1 + 2 "
Output: 3
Example 3:

Input: s = “(1+(4+5+2)-3)+(6+8)”
Output: 23

Constraints:

1 <= s.length <= 3 * 105
s consists of digits, ‘+’, ‘-’, ‘(’, ‘)’, and ’ '.
s represents a valid expression.
‘+’ is not used as a unary operation (i.e., “+1” and “+(2 + 3)” is invalid).
‘-’ could be used as a unary operation (i.e., “-1” and “-(2 + 3)” is valid).
There will be no two consecutive operators in the input.
Every number and running calculation will fit in a signed 32-bit integer.

解法1:参考labuladong
注意:

  1. helper()里面的index必须用&,因为递归回来后,index的值就已经递增了。
  2. 递归完后,c=s[index]是更新后的index对应的字符。
  3. 如果不是最后一个字符,遇到运算符(非数字又非空格),要进switch()处理。如果是最后一个字符,不管是什么(空格也好,数字也好),也要进switch()处理,不然这最后一个数字就丢掉了。
class Solution {
public:
    int calculate(string s) {
        int index = 0;
        return helper(s, index);
    }
private:
    int helper(string &s, int &index) {
        stack<int> stk;
        int sLen = s.size();
        char sign = '+';
        int num = 0;
        int res = 0;
        for (; index < sLen; index++) {
            char c = s[index];
            if (c == '(') {
                index++;
                num = helper(s, index);
            }
            c = s[index];
            if (isdigit(c)) {
                num = num * 10 + (c - '0');
            } 
            if ((!isdigit(c) && c != ' ') || index == sLen - 1) { //(c == '+' || c == '-' || c == '*' || c == '/') or reach the end
                switch (sign) {
                    case '+':
                        stk.push(num);
                        break;
                    case '-':
                        stk.push(-num);
                        break;
                    case '*':
                        stk.push(stk.top() * num);
                        stk.pop();
                        break;
                    case '/':
                        stk.push(stk.top() / num);
                        stk.pop();
                        break;
                    default:
                    break;
                }
                sign = c;
                num = 0;
            }
            if (c == ')') {
                index++;
                break;
            }
        }
        
        while (!stk.empty()) {
            res += stk.top();
            stk.pop();
        }
        return res;
    }
};

解法2:差不多的做法。只是没用helper()。

class Solution {
public:
    /**
     * @param s: the given expression
     * @return: the result of expression
     */
    int calculate(string &s) {
        int len = s.size();
        stack<int> stk;
        int res = 0, num = 0;
        int sign = 1;
        int bracket_cnt = 0;
        int i = 0;
        while (i < len) {
            char c = s[i];
            if (isdigit(c)) {
                num = num * 10 + c - '0';
            }
            else if (c == '+' || c == '-') {
                res += num * sign;
                num = 0;
                sign = (c == '+') ? 1 : -1;
            }
            else if (c == '(') {
                int orig_pos = i + 1;
                bracket_cnt = 1;
                while (i < len && bracket_cnt > 0) {
                    i++;
                    if (s[i] == '(') bracket_cnt++;
                    else if (s[i] == ')') bracket_cnt--;
                }
                
                string s2 = s.substr(orig_pos, i - orig_pos);
                int temp_res = calculate(s2);
                res += sign * temp_res;
                num = 0;
            }
            i++;
        }
        if (num != 0) {
            res += sign * num;
        }
        return res;
    }
};
  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值