基本计算器 II

476 阅读1分钟

基本计算器 II

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

整数除法仅保留整数部分。

 

示例 1:

输入:s = "3+2*2"
输出:7

示例 2:

输入:s = " 3/2 "
输出:1

示例 3:

输入:s = " 3+5 / 2 "
输出:5

 

提示:

  • 1 <= s.length <= 3 * 105
  • s 由整数和算符 ('+', '-', '*', '/') 组成,中间由一些空格隔开
  • s 表示一个 有效表达式
  • 表达式中的所有整数都是非负整数,且在范围 [0, 231 - 1] 内
  • 题目数据保证答案是一个 32-bit 整数

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/ba… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

首先在字符串中混有空格,所以进行遍历的时候,要去除空格。

先乘除,后加减

我们可以定一个数组,存放需要进行计算的数字let stack = []

把所有需要计算的数字存入stack中,然后stack.reduce()计算总和

图解

1.png

2.png

3.png

4.png

5.png

6.png

7.png

8.png

9.png

代码


var calculate = function (s) {
    // 创建一个数组,存放数字
    let stack = [];
    // 这个加号作用是进行第一次计算时,第一个数需要加入stack数组中
    let preSign = '+';
    // num获取当前数字
    let num = 0;
    for (let i = 0; i < s.length; i++) {
        // 当字符串该字符是数字时,使用num保存
        if (!isNaN(s[i]) && s[i] != ' ') {
            // 举例:
            // 遍历到'123'中的'1'时,当前num为0,则0*10 + 1 = 1
            // 第二次遍历到'2'时,当前num为1,则1*10 + 2 = 12
            // 第三次遍历到'3'时,当前num为12,则12*10 + 3 = 123
            // 乘10的目的是为了应付多位数的情况
            num = num * 10 + Number(s[i]);
        }
        // 当字符串该字符是运算符号时(或遍历到最后一个字符),进入该if
        if (isNaN(s[i]) || i == s.length - 1) {
            // 当第一次进入该if中时,表示第一次遇到运算符号,但是运算符号后面的数字还没拿到
            // 先把运算符号前面的数字加到stack中
            // 例:1*2+3
            // 遍历到第一个运算符号*时,把1push到stack中
            // 然后保存第一个*号到preSign中
            // 第二次进入该if,表示遍历到第二个运算符号+,preSign还是*号
            // 所以先1*2 = 2,把1pop掉,把1*2的结果push到stack中,然后preSign值变为+号
            // 最后一次进入该if,表示已经遍历完了,preSign还是+号,所以把3push进stack中
            switch (preSign) {
                case '+':
                    stack.push(num);
                    break;
                case '-':
                    stack.push(-num);
                    break;
                case '*':
                    stack.push(stack.pop() * num);
                    break;
                case '/':
                    stack.push(stack.pop() / num | 0);
                    break;
            }
            // 为啥要赋值,不直接用s[i]呢?
            // 因为使用s[i]不会计算符号后面的数
            // 需要获取到计算符号后面的数,再使用preSign保存的符号进行计算
            preSign = s[i];
            num = 0;
        }
    }
    // 返回stack数组中的值相加的结果即可
    return stack.reduce((a, b) => a + b);
};