一、题目描述
给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。
整数除法仅保留整数部分。
示例 1:
输入: s = "3+2*2"
输出: 7
示例 2:
输入: s = " 3/2 "
输出: 1
示例 3:
输入: s = " 3+5 / 2 "
输出: 5
提示:
1 <= s.length <= 3 * 105s由整数和算符('+', '-', '*', '/')组成,中间由一些空格隔开s表示一个 有效表达式- 表达式中的所有整数都是非负整数,且在范围
[0, 231 - 1]内 - 题目数据保证答案是一个 32-bit 整数
二、分析
本题要求我们将输入字符串的运算结果返回,我们可以通过两个 栈 来维护当前的运算符和数值,每次取出栈顶的元素进行计算
- 创建运算符栈存储运算符
- 创建数值栈存储数值
- 遍历输入字符串表达式,将对应运算符和数值存储入栈
- 每次参与运算的值为数值栈的栈顶两个值,运算结果再压入数值栈
- 当运算符栈为空时,数值栈中将会剩余一个值,就是我们要求得的结果
代码如下:
/**
* @param {string} s
* @return {number}
*/
var calculate = function(s) {
s = s.trim(); // 去掉字符串两边的空格
const stack = [];
let preSign = '+'; // 记录符号,默认第一个数字前是个+,对数字没有任何影响
let num = 0; // 记录当前数字
const n = s.length;
for(let i=0;i<n;++i){
// 找出所有数字
if(!isNaN(Number(s[i])) && s[i] !== ' '){
num = num * 10 + s[i].charCodeAt() - '0'.charCodeAt();
}
// 找出所有符号
if(isNaN(Number(s[i])) || i === n-1){
switch(preSign){
case '+':
stack.push(num); // 如果是+直接向栈中添加
break;
case '-':
stack.push(-num); // 如果是-,向栈中添加-num,相加时相当于做减法
break;
case '*':
stack.push(stack.pop() * num); // 如果是*,向栈中添加当前数字和栈顶元素相乘的结果,因为乘除法优先级更高
break;
default:
stack.push(parseInt(stack.pop() / num)); // 是 / ,则向栈中添加栈顶元素 / 当前数字并只取整数的结果
break;
}
preSign = s[i]; // 替换preSign 的值
num = 0;
}
}
let ans = 0; // 记录计算后的结果
while(stack.length){
// 将所有栈顶元素相加
ans += stack.pop();
}
return ans;
}
欢迎讨论哦