正题
基本计算器 II
给你一个字符串表达式 s
,请你实现一个基本计算器来计算并返回它的值。
整数除法仅保留整数部分。
示例 1:
输入:s = "3+2*2"
输出:7
示例 2:
输入:s = " 3/2 "
输出:1
示例 3:
输入:s = " 3+5 / 2 "
输出:5
分析:
基本计算器即是解决 加减乘除 的问题,首先第一个想到的办法就是遍历字符串,那么问题来了,首先要区分是数字还是符号,接着遍历单个字符如果遇到大于10的数怎么处理呢?假设一种情况 34*2,那么遍历的时候我就只会拿到数字3和数字4,如何看成是数字34??
突然想到,如果说有一个栈,将字符串遍历不停讲字符push进栈,那么如果连续push进去的是数字,不就可以得到34了嘛?
所以这题的根本解决思路可能还是要放到栈上。
那么首先解决第一个问题,确认遍历的字符是数字还是符号,这个用正则表达式,判断是否为数字即可,非数字我们就默认为是符号: /\D/.test(char)
其次是运算顺序的问题,先乘除后加减,那么我们可以认为,当栈中出现乘除法的时候可以立即计算,然后将结果直接推入栈中,这样栈中就只剩下加减法,最后再一次计算即可。
/**
* @param {string} s
* @return {number}
*/
var calculate = function(s) {
let stack = [], sign = '+', number = ''
for(let index = 0 ; index < s.length || number; index++) {
const char = s[index]
if (char === ' ') continue
if (/\D/.test(char)) {
if (sign === '+') {
stack.push(parseInt(number))
} else if (sign === '-') {
stack.push(-parseInt(number))
} else if (sign === '*') {
stack.push(stack.pop() * parseInt(number))
} else {
stack.push(stack.pop() / parseInt(number) | 0)
}
sign = char
number = ''
} else {
number = number + char
}
}
console.log(stack)
return stack.reduce((p, v) => p + v)
};
主要思路在于
- 栈决定执行顺序
- 字符拼接成数字包括>10的数字
- 将数字暂存,直到出现符号
- 如果是非乘除那么直接推入栈,如果是乘除那么先使用暂存的数字计算过后再推入栈
- 栈求和