「这是我参与2022首次更文挑战的第12天,活动详情查看:2022首次更文挑战」
前言
今天到了设计计算器的日子了,这一次是加减乘除都包含的基本计算器,主要还是运用我们栈的数据结构来处理。
题目描述
227. 基本计算器 II
给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。
整数除法仅保留整数部分。
解题思路
题给字符串:
有效的表达式字符串,由非负整数和运算符('+','-','*','/')组成,中间是一些空格
我们的目的:
将字符串表达式的整数和运算符解析出来,模拟计算器的运算过程将最终计算结果计算出来
逻辑思路
-
要模拟计算器,我们需要把字符串中的整数和符号给拿到,整数需要考虑不止一位数,可以想象num = num * 10 + xx的类似,符号有4种可以用switch case判断
-
遇到数字还是遇到符号开始计算?
1)符号我们设为'+',肯定是我们遇到了下一个符号,才知道上一步运算的结尾在哪里,要完成计算的话,我们还需要前面的数字num得存起来,然后利用前一个符号进行计算,得出这一步的计算结果,那么我们需要把每一步的运算结果存起来,可以用栈2)如果前一位符号是*或者/呢,我们需要把栈顶中数字取出来与我们最近的num进行计算再存入栈中即可
3)到了字符串末尾也就是最后一个整数的时候,我们也需要进行运算
4)最后我们取出栈中所有元素求和就是我们计算器的最终运行结果
开始解题
var calculate = function(s) {
let str = s.trim(); // 去除字符串两边空格,简化一下
let preSign = "+",numStack = []; // 预设符号"+", 运算数字栈初始化
let num = 0; // 每次运算后一个临时整数
for(let i = 0; i < str.length; i++){
if(!isNaN(Number(str[i])) && str[i] !== ' ') { // 过滤不止一位的整数,遇到空格就停止
num = num * 10 + Number(str[i]);
}
if(isNaN(Number(str[i])) || i === str.length-1) { // 遇到符号和最后一位整数时候进行运算
switch(preSign) { // 使用前一位符号进行运算
case "+":
numStack.push(num);
break;
case "-":
numStack.push(-num);
break;
case "*":
numStack.push(numStack.pop() * num);
break;
case "/":
numStack.push(numStack.pop() / num | 0); // 这里用|去除小数部分
break;
}
preSign = str[i]; // 用完符号,保存本次遍历的符号作为下次的运算符
num = 0; // 运算的临时数字重置为0
}
}
let sum = 0;
while(numStack.length) { // 将栈中所有运算结果相加
sum += numStack.pop();
}
return sum;
};