题目描述
给你一个字符串表达式 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… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
整体上先乘除后加减 。先遍历一遍,把需要加减的数先存起来,需要乘除的直接运算,再遍历一遍把左右需要加减的加起来。
所以到最后其实都是做加法
- 用数组来记录待加减的项
- 遍历字符串,判断每个字符类型,表达式一定由数字开始,由数字结尾。
- 每当遇到符号,则代表完整的统计好了一个数。
- 然后来处理这个数,并判断前一个符号,如果是加,则代表目前数字是待加项,直接加入数组。
- 是减号则,变负数再加入数组
- 乘号则与数组最后一个数相乘
- 除号则用最后一个数除以当前数
遍历完成,再把数组所有元素相加,则就是最后运算结果
代码
// 去掉空格后,遍历字符串
/**
* @param {string} s
* @return {number}
*/
var calculate = function(s) {
s=s.replace(/\s/g,"").split('');//去空格
let num=0;//记录数字,在每次遇到符号时候结算
let stack=[];
let n=s.length;
let preIcon='+';//记录之前出现的符号,第一个数字就当是0+ 所以默认加号
for(let i=0;i<n;i++){
//遍历字符串
if(!isNaN(parseInt(s[i]))){
//是数字,添加到记录数字的位数
num=num*10+parseInt(s[i])
}else{
//遇到符号代表,上一个数字已经统计完毕,该考虑这个数字的归属问题
//不是数字,就要判断上一个符号
actionIcon();
preIcon=s[i];//重新赋值符号
num=0;//并重新开始统计数字
}
}
//由于最后一个数字,没有符号来结尾,所以遍历完毕,运算下最后一个数字
actionIcon();
function actionIcon(){
switch(preIcon){
case '+'://如果上一个运算符是加号,就直接放入栈
stack.push(num);
break;
case '-'://减法则变成负数,再放入栈
stack.push(-num);
break;
case '*'://乘法则把栈里最后一个数字和当前数字相乘
let last=stack.pop();
stack.push(last*num);
break;
case '/'://触发则用栈里最后一个数组除以当前数字取整
let last1=stack.pop();
stack.push(parseInt(last1/num));
break;
default:
}
}
console.log(stack)
//最后再把栈里的所有元素相加
let result=0;
for(let i=0;i<stack.length;i++){
result+=stack[i];
}
return result;
};