题目
给你一个字符串表达式 s
,请你实现一个基本计算器来计算并返回它的值。
整数除法仅保留整数部分。
示例1
输入: s = "3+2*2"
输出: 7
复制代码
示例2
输入: s = " 3/2 "
输出: 1
复制代码
解题思路
模拟实现
题目要求只有'+', '-', '*', '/'四则运算,根据四则运算优先级应该先计算乘除,再计算加减
模拟计算过程;
假设有
s = "3+2*2"
复制代码
申请一个空数组list;将数据存放list中;
const list = ['3','+','2','*',2];
第一步:枚举数组list,并将数组list中乘除计算出结果放在原处;
得到: list = ['3','+','4']
第二步:再次枚举数组,将数组中list中加减计算出结果
得到: list = [4];
返回结果即可
根据上述思路编辑代码如下:
var calculate = function (s) {
const string = s.replace(/^\s+|\s+$/g, '');
let len = string.length;
const list = [];
let t = '';
for (let i = 0; i < len; i++) {
const c = string[i];
if (['+', '-', '*', '/'].includes(c)) {
list.push(t, c);
t = '';
} else {
t += c;
}
}
if (t) {
list.push(t);
}
//console.log('list', list);
// 计算乘法;
len = list.length;
if (len === 1) return list[0];
const array = [];
for (let i = 0; i < len; i++) {
const t = array[array.length - 1];
if (t === '*') {
array.pop();
const after = array.pop();
const n = after * list[i];
array.push(n);
} else if (t === '/') {
array.pop();
const after = array.pop();
const n = Math.floor(after / list[i]);
array.push(n);
} else {
array.push(list[i]);
}
}
let result = 0;
let sign = 1;
for (let i = 0; i < array.length; i++) {
const n = array[i];
if (n === '+') {
sign = 1;
}
if (n === '-') {
sign = -1;
}
if (!['+', '-'].includes(n)) {
result += sign * n;
}
}
return Math.floor(result);
};
复制代码
上述思路虽然没错,但是代码写起来太繁琐了;需要一遍一遍的遍历数组;先计算乘除,后计算加减;能不能优化一下代码呢?
当然可以:
优化后代码如下:
优化了乘除,在第一次枚举字符串时,同时进行乘除操作,将乘除后的结果放在数组中;再次枚举数组只需对数据求和即可得到答案
var calculate = function(s) {
s = s.trim();
const stack = new Array();
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);
break;
case '*':
stack.push(stack.pop() * num);
break;
default:
stack.push(stack.pop() / num | 0);
}
preSign = s[i];
num = 0;
}
}
let ans = 0;
while (stack.length) {
ans += stack.pop();
}
return ans;
};
复制代码