【JS每日一算法:剑指Offer系列】🟥167. 基本计算器(栈+递归)

179 阅读2分钟

给你一个字符串表达式 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位 整数

题解:

个人博客

更多JS版本题解点击链接关注该仓库👀

/**
 * @description: 栈+递归  TC:O(n)  SC:O(n)
 * @author: JunLiangWang
 * @param {*} s 给定字符串
 * @return {*}
 */
function stackAndRecursion(s) {
    /**
     * 本方案使用栈+递归的方式
     */

    /**
     * @description: 遇到(递归计算括号内结果
     * @author: JunLiangWang
     * @param {*} index 字符串位置
     * @return {*}
     */    
    function recusion(index) {
        // 栈
        let stack = [], 
        // 前面的符号
        sign = '+', 
        // 数值 
        number = 0, 
        // 遍历到字符串的位置
        i = index;
        while (i < s.length) {
            let char = s[i];
            // 当前字符如果是数字,那么使用number记录
            if (!isNaN(char) && char != ' ') number = number * 10 + char * 1
            // 当前字符如果不是数字,但是左括号,此时递归获取括号的数字
            else if (char == '(') {
                let temp = recusion(i + 1)
                number = temp[0]
                i = temp[1]
            }
            // 当前字符如果不是数字且不为空格,或者当前字符为最后一个字符
            // 此时需要将数字push到栈中,并重置number与sign
            if ((isNaN(char) && char != ' ') || s.length - 1 <= i) {
                switch (sign) {
                    case '+':
                        stack.push(number)
                        break;
                    case '-':
                        stack.push(-number)
                        break;
                    case '*':
                        stack.push(stack.pop() * number)
                        break;
                    case '/':
                        stack.push(stack.pop() / number)
                        break;
                }
                number = 0
                sign = char
            }
            // 如果当前字符为右括号,那么需要结束递归
            if (char == ')') break;
            i++
        }
        number = 0
        // 将栈中元素求和
        stack.forEach((val) => number += val)
        return [number, i];
    }

    // 执行递归,返回结果
    return recusion(0)[0]
}