携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第23天,点击查看活动详情
题目(Basic Calculator)
链接:https://leetcode-cn.com/problems/basic-calculator
解决数:878
通过率:42.2%
标签:栈 递归 数学 字符串
相关公司:amazon facebook microsoft
给你一个字符串表达式 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 * 105s由数字、'+'、'-'、'('、')'、和' '组成s表示一个有效的表达式- '+' 不能用作一元运算(例如, "+1" 和
"+(2 + 3)"无效) - '-' 可以用作一元运算(即 "-1" 和
"-(2 + 3)"是有效的) - 输入中不存在两个连续的操作符
- 每个数字和运行的计算将适合于一个有符号的 32位 整数
思路
- 反转字符串转为
数组。pop即从左到右遍历字符串 空格忽视。(开始递归。非数字,+/-入栈,*/除与栈头运算入栈。)结束递归数字累加。返回栈的累加和
代码
var calculate = function(s) {
var q = [], n = '', f = '+', a = typeof s === 'string' ? Array.from(s).reverse() : s
while(a.length || n) {
var p = a.pop()
if (p === ' ') continue
if (p === '(') {
n = calculate(a)
} else if (/\D/.test(p)) {
switch (f) {
case '+':
q.push(n)
break;
case '-':
q.push(-n)
break;
case '*':
q.push(q.pop() * n)
break;
case '/':
q.push(q.pop() / n | 0)
}
if (p === ')') break
f = p, n = ''
} else n += p
}
return q.reduce((p, v) => p + (v | 0), 0)
};
也可
var calculate = function (s) {
let ans = 0;
let num_stack = [];
let op_stack = [];
let sign = 1;
for (let i = 0; i < s.length; i++) {
if (s[i] == ' ') continue;
if (s[i] == '+' || s[i] == '-') sign = s[i] == '+' ? 1 : -1;
else if (s[i] >= '0' && s[i] <= '9') {
let num = parseInt(s[i]);
while (i < s.length - 1 && s[i + 1] >= '0' && s[i + 1] <= '9') {
num = num * 10 + parseInt(s[++i]);
}
ans += sign * num;
} else if (s[i] == '(') {
num_stack.push(ans);
op_stack.push(sign);
ans = 0;
sign = 1;
} else {
ans = num_stack.pop() + ans * op_stack.pop();
}
}
return ans;
};
还可
var calculate = function (s) {
let sign = 1, res = 0, valStack = [], signStack = []
const isNumber = v => v <= '9' && v >= '0'
for (let i = 0; i < s.length; i++) {
if (s[i] === '+') sign = 1
else if (s[i] === '-') sign = -1
else if (s[i] === '(') {
valStack.push(res)
signStack.push(sign)
res = 0
sign = 1
}
else if (s[i] === ')') res = res * signStack.pop() + valStack.pop()
else if (isNumber(s[i])) {
let n = s[i]
while (i+1 && isNumber(s[i+1])) n += s[(i++)+1]
res += sign * (+n)
}
}
return res
};