题目介绍
给你一个字符串表达式 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… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
由于优先乘除法的计算,所以我们先算乘除法,得到的结果再放回栈中,如果是减号取反后再入栈,最后栈中剩余的元素逐个相加即可,具体的细节
- 由于遍历的是字符串,怎么获取完整的数字 如:'123',我们先把数字num为0, 每次进位都是乘以10的,然后把当前字符串转换为数字后相加, 即 num * 10 + Number(si)
- 判断当前字符是否是计算符,或者是否是字符的最后一个字符串。 计算乘除的时候怎么获取,相乘或者相除的两个数,我们先要定义一个preOps标识,默认是+,如果是加减号就把num压入栈中,如果遇到乘号或者除号,就取出占中的尾部元素,尾部元素就是*或者除号的前面的数字,num就是后面的那个数字,每次入栈完成要把num重置为0,preOps标识变成当前计算符号
代码
var calculate = function(s) {
// 要去调前后空串,否则,最后一个为空串的时候没法判断
s = s.trim()
let preOper = '+'
let stack = []
let num = 0 // 遇到计算符号的时候才把num入栈
for (let i = 0; i < s.length; i++) {
let si = s[i]
if (si === ' ') continue
if (!isNaN(Number(si))) {
num = num * 10 + Number(si)
}
if (isNaN(Number(si)) || i === s.length - 1) {
switch(preOper) {
case '+':
stack.push(num)
break
case '-':
stack.push(-num)
break
case '*':
stack.push(stack.pop() * num)
break
case '/':
stack.push(parseInt((stack.pop() / num)))
break
}
num = 0
preOper = si
}
}
let ant = 0
if (stack.length) {
ant = stack.reduce((t, i) => t += i)
}
return ant
};