「前端刷题」224.基本计算器(HARD)

100 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第23天,点击查看活动详情

题目(Basic Calculator)

链接:https://leetcode-cn.com/problems/basic-calculator
解决数:878
通过率:42.2%
标签:栈 递归 数学 字符串 
相关公司:amazon facebook microsoft 

给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。

注意:不允许使用任何将字符串作为数学表达式计算的内置函数,比如 eval() 。

 

示例 1:

输入: s = "1 + 1"
输出: 2

示例 2:

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

示例 3:

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

 

提示:

  • 1 <= s.length <= 3 * 105
  • s 由数字、'+''-''('')'、和 ' ' 组成
  • s 表示一个有效的表达式
  • '+' 不能用作一元运算(例如, "+1" 和 "+(2 + 3)" 无效)
  • '-' 可以用作一元运算(即 "-1" 和 "-(2 + 3)" 是有效的)
  • 输入中不存在两个连续的操作符
  • 每个数字和运行的计算将适合于一个有符号的 32位 整数

思路

  • 反转字符串转为数组pop从左到右遍历字符串
  • 空格忽视。(开始递归。非数字+/-入栈,*/除与栈头运算入栈。)结束递归
  • 数字累加。返回的累加和

代码

var calculate = function(s) {
    var q = [], n = '', f = '+', a = typeof s === 'string' ? Array.from(s).reverse() : s
    while(a.length || n) {
        var p = a.pop()
        if (p === ' ') continue
        if (p === '(')  {
            n = calculate(a)
        } else if (/\D/.test(p)) {
            switch (f) {
                case '+':
                    q.push(n)
                break;
                case '-':
                    q.push(-n)
                break;
                case '*':
                    q.push(q.pop() * n)
                break;
                case '/':
                    q.push(q.pop() / n | 0)
            }
            if (p === ')') break
            f = p, n = ''
        } else n += p
    }
    return q.reduce((p, v) => p + (v | 0), 0)
};

也可

var calculate = function (s) {
    let ans = 0;
    let num_stack = [];
    let op_stack = [];
    let sign = 1;
    for (let i = 0; i < s.length; i++) {
        if (s[i] == ' ') continue;
        if (s[i] == '+' || s[i] == '-') sign = s[i] == '+' ? 1 : -1;
        else if (s[i] >= '0' && s[i] <= '9') {
            let num = parseInt(s[i]);
            while (i < s.length - 1 && s[i + 1] >= '0' && s[i + 1] <= '9') {
                num = num * 10 + parseInt(s[++i]);
            }
            ans += sign * num;
        } else if (s[i] == '(') {
            num_stack.push(ans);
            op_stack.push(sign);
            ans = 0;
            sign = 1;
        } else {
            ans = num_stack.pop() + ans * op_stack.pop();
        }
    }
    return ans;
};

还可

var calculate = function (s) {
    let sign = 1, res = 0, valStack = [], signStack = []
    const isNumber = v => v <= '9' && v >= '0'
    for (let i = 0; i < s.length; i++) {
        if (s[i] === '+') sign = 1
        else if (s[i] === '-') sign = -1
        else if (s[i] === '(') {
            valStack.push(res)
            signStack.push(sign)
            res = 0
            sign = 1
        }
        else if (s[i] === ')') res = res * signStack.pop() + valStack.pop()
        else if (isNumber(s[i])) {
            let n = s[i]
            while (i+1 && isNumber(s[i+1])) n += s[(i++)+1]
            res += sign * (+n)
        }
    }
    return res
};