772. 基本计算器 III
实现一个基本的计算器来计算简单的表达式字符串。
表达式字符串只包含非负整数,算符 +、-、*、/ ,左括号 ( 和右括号 ) 。整数除法需要 向下截断 。
你可以假定给定的表达式总是有效的。所有的中间结果的范围均满足 [-231, 231 - 1] 。
注意: 你不能使用任何将字符串作为表达式求值的内置函数,比如 eval() 。
示例 1:
输入: s = "1+1"
输出: 2
示例 2:
输入: s = "6-4/2"
输出: 4
示例 3:
输入: s = "2*(5+5*2)/3+(6/2+8)"
输出: 21
提示:
1 <= s <= 104s由整数、'+'、'-'、'*'、'/'、'('和')'组成s是一个 有效的 表达式
/**
* @param {string} s
* @return {number}
*/
var calculate = function(s) {
const suffixExpression = []; // 逆波兰表达式
const stack = []; // 符号栈
// 符号优先级权重
const map = {
'*': 3,
'/': 3,
'+': 2,
'-': 2,
'(': 1
}
let num = 0;
let preNumFlg = false;
for (const ch of s) {
if (isNumber(ch)) {
num = num * 10 + Number(ch);
preNumFlg = true;
} else {
if (preNumFlg) {
suffixExpression.push(num);
num = 0;
preNumFlg = false;
}
if (ch === ' ') {
continue;
}
if (ch === '(') {
stack.push('(')
} else if (ch === ')') {
let cur = stack.pop();
while (cur !== '(') {
suffixExpression.push(cur);
cur = stack.pop();
}
} else {
while (stack.length && map[stack[stack.length - 1]] >= map[ch]) {
suffixExpression.push(stack.pop());
}
stack.push(ch)
}
}
}
if (preNumFlg) {
suffixExpression.push(num);
}
while (stack.length) {
suffixExpression.push(stack.pop());
}
for (const ch of suffixExpression) {
switch (ch) {
case '*': {
const num2 = stack.pop();
const num1 = stack.pop();
stack.push(num1 * num2);
break;
}
case '/': {
const num2 = stack.pop();
const num1 = stack.pop();
const result = num1 / num2 < 0 ? Math.ceil(num1 / num2) : Math.floor(num1 / num2);
stack.push(result);
break;
}
case '+': {
const num2 = stack.pop();
const num1 = stack.pop();
stack.push(num1 + num2);
break;
}
case '-': {
const num2 = stack.pop();
const num1 = stack.pop();
stack.push(num1 - num2);
break;
}
default: {
stack.push(Number(ch));
}
}
}
return stack[0];
};
function isNumber(ch) {
return !isNaN(ch);
}