前端算法小白攻略28-leetcode(基本计算器)

265 阅读2分钟

「这是我参与2022首次更文挑战的第12天,活动详情查看:2022首次更文挑战

前言

今天到了设计计算器的日子了,这一次是加减乘除都包含的基本计算器,主要还是运用我们栈的数据结构来处理。

题目描述

227. 基本计算器 II

给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。

整数除法仅保留整数部分。

解题思路

题给字符串: 有效的表达式字符串,由非负整数和运算符('+','-','*','/')组成,中间是一些空格
我们的目的: 将字符串表达式的整数和运算符解析出来,模拟计算器的运算过程将最终计算结果计算出来
逻辑思路

  1. 要模拟计算器,我们需要把字符串中的整数和符号给拿到,整数需要考虑不止一位数,可以想象num = num * 10 + xx的类似,符号有4种可以用switch case判断

  2. 遇到数字还是遇到符号开始计算?
    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;
};