基本计算器 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()计算总和
图解
代码
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);
};