基本计算器II
给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。
整数除法仅保留整数部分。
解题代码
- 将表达式拆成两部分,一部分包含操作数,一部分包含运算符。
- 分别入栈,入栈运算符时判断当前优先级是否小于前面栈顶元素优先级,如果是,那么需要先处理完前面栈中运算符
var calculate = function(s) {
let numStack = []; // 存储操作数
let opsStack = []; // 存储运算符
let num = 0;
s = s.replace(/\s/g,"").split(""); // 去除空格并拆分成数组
s.push("@"); // 保证末尾有一个操作符可以进行递归循环判断计算
for (let i = 0; i < s.length; i++) {
const op = s[i];
if (level(op) === 0) {
num = num * 10 + Number(op); // 非个位数字进行累加,如 123 + 5 + 1 -> [1,2,3,+,5,+,1],遇到运算符时,才进行操作数入栈
continue;
}
numStack.push(num); // 操作数入栈
num = 0; // 前一个操作数入栈后,重置
while (opsStack.length && level(op) <= level(opsStack[opsStack.length - 1])) { // 当前运算符优先级小于栈顶运算符优先级,进行计算
const b = numStack.pop(); // 操作数栈依次出栈两个元素进行计算、例子 如 3 + 2 * 5 -> nStack = [3,2,5]
const a = numStack.pop(); // 如计算 a * b ,此时 a b -> [2(a),5(b)];
const op = opsStack.pop(); // oStack = [+,*,](未入栈当前操作符为@),弹出 *
numStack.push(calc(a, b, op)); // 计算结果,将结果重新压入操作数栈 = [3,10] ,此时 oStack = [+], 当前 @ 操作符依然小于,那么循环条件依然可以进行 res -> [13] oStack = [];
}
opsStack.push(op); // 处理完前面运算符优先级计算之后,压入当前运算符
}
return numStack.pop();
};
var level = function(op) {
switch (op) {
case "@": return -1;
case "+": ;
case "-": return 1;
case "*": ;
case "/": return 2;
}
return 0;
}
var calc = function(a,b,op) {
a = Number(a);
b = Number(b);
switch (op) {
case "+": return a + b;
case "-": return a - b;
case "*": return a * b;
case "/": return a / b >> 0; // 保留整数
}
return 0
}