欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

leetcode 277 基本计算器 Basic Calculator II (单栈,单次遍历,思路简单)

程序员文章站 2022-07-15 12:24:04
...

leetcode 277 基本计算器 Basic Calculator II


因只有两个优先级:+ - or * / 所以相对比较简单
只要你点开了这篇,就一定可以学会了出去!!

思路:遍历一次字符串
1.遇到空格跳过
2.若碰到数字则取得该数字全部字符入栈
3.若碰到加减则把入栈数字*原符号追加进结果,更新符号
4.若碰到乘除则把入栈数字与符号后的数字运算后重新入栈

1.定义全局变量

这里我们需要三个全局变量,stack[]作为数字栈存放还未计算完成的数,
sign存放已经遍历到但还未参与计算的+ or -,定义为 1 or -1(为什么定义为这两个值,为了方便相乘鸭!!),初始为+,
answer存放计算结果。

2.遍历

Number

当遇到0-9的数字时,万不可直接push进栈,因为有可能是几十,几百或者几千。首先要做的是找全这个数字。

if (s[i]>=0 && s[i]<=9) {   //maybe 24, 109 and so on
        let k =i+1;
        while(s[k]>=0 && s[k]<=9 ) k++;  //找到此数字最后一个index,此时k为此index+1
       if(k!==(i+1)){   //两位数以上
            stack.push(s.substring(i,k));
            i = k-1;   //因为for循环中还有一次i++
       }else {   //一位数
           stack.push(s[i]);
       }
    }

加减

加减其实计算的是前一个加减符号到这一个之间的值,所以是用之前存放的sign*这一段的计算结果(stack.pop())

if (s[i] == '+' || s[i] == '-'){
        if(stack.length) answer += stack.pop() * sign;  //  这里加if判断是避免第一个数字是负数的情况
        sign = (s[i] == '+' ?  1 : -1);  //更新sign
    }

乘除

乘除计算的是当前这个符号前后两个数字,计算结果入栈。(符号前数字在栈中,符号后数字需要用上述Number方法找全数字)

if (s[i] == '*' || s[i] == '/') {
		//找符号后全数字
        let j = i+1;
        while (s[j]==' ') j++;  //有空格则startIndex后移
        let k = j+1;
        while(s[k]>=0 && s[k]<=9 ) k++;  
        let newWord = null;
        if(k == (j+1)) newWord = s[j];
        else newWord = s.substring(j,k);
		//计算
        if(s[i] == '*') stack.push( stack.pop() * Number(newWord));
        else  stack.push(Math.floor(stack.pop() / Number(newWord))); 
       
        i = k-1; 
    }

如此,便完成了所有逻辑块。

全部代码

var calculate = function(s) {
let sign = 1 ; //1 equal + ; -1 equal -
let stack = [];  //存放数字
let answer = 0;
for(let i = 0 ; i <s.length ; i++){
    if(s[i] == ' ') continue;  // space pass
    else if (s[i]>=0 && s[i]<=9) {   //maybe 24, 109 and so on
        let k =i+1;
        while(s[k]>=0 && s[k]<=9 ) k++;  //找到此数字最后一个index,此时k为此index+1
       if(k!==(i+1)){   //两位数以上
            stack.push(s.substring(i,k));
            i = k-1;   //因为for循环中还有一次i++
       }else {   //一位数
           stack.push(s[i]);
       }
    }
    else if (s[i] == '+' || s[i] == '-'){
        if(stack.length) answer += stack.pop() * sign;  //  这里加if判断是避免第一个数字是负数的情况
        sign = (s[i] == '+' ?  1 : -1);  //更新sign
    }else if (s[i] == '*' || s[i] == '/') {
		//找符号后全数字
        let j = i+1;
        while (s[j]==' ') j++;  //有空格则startIndex后移
        let k = j+1;
        while(s[k]>=0 && s[k]<=9 ) k++;  
        let newWord = null;
        if(k == (j+1)) newWord = s[j];
        else newWord = s.substring(j,k);
		//计算
        if(s[i] == '*') stack.push( stack.pop() * Number(newWord));
        else  stack.push(Math.floor(stack.pop() / Number(newWord))); 
       
        i = k-1; 
    }
}
//计算最后一个剩余数字
while(stack.length){
    answer += Number(stack.pop()) * sign;  //leave the last number
}
return answer;
};

如有任何不解,欢迎随时交流