[路飞]_LeetCode题227基本计算器 II

354 阅读2分钟

题目描述

给你一个字符串表达式 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… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解思路

  1. 先把字符串内的空格去掉。
  2. 把算式字符串转换为算式数组,方便循环。
  3. 按照先计算乘除在计算加减的原则进行两次遍历。
  4. 算乘除时,遇到数字就存起来,下一个必然是运算符,如果下一个运算符是“+”,我们就把存起的数推入栈顶,如果是“-”,我们就把存起的数取反推入栈顶,继续遍历。遇到“*”或“/”我们就将栈顶元素取出与当前存起的数做乘除计算,将计算结果推入栈顶。
  5. 乘除计算完成后,栈的所有元素都为待相加的整数,求和即可。

ps:在最后求和的时候,按照加法运算法则,应该从左往右依次运算,所以应该使用arrar.shift()方法更为贴切,但是使用array.shift()提交系统判定运算超时,使用array.pop()就提交通过,我不明所以,如有大神知晓原因望指教。

题解代码

 * @lc app=leetcode.cn id=227 lang=javascript
 *
 * [227] 基本计算器 II
 */

// @lc code=start
/**
 * @param {string} s
 * @return {number}
 */

//字符串算式转为数组算式
var toArrayFormula = function(strFormula){
  let num = "";
  let calculateArray = [];
  for (let i = 0; i < strFormula.length; i++) {
    if (strFormula[i] !== "+" && strFormula[i] !== "-" && strFormula[i] !== "*" && strFormula[i] !== "/") {
      num += strFormula[i]
    }else{
      calculateArray.push(num);
      calculateArray.push(strFormula[i]);
      num = "";
    }
  }
  calculateArray.push(num);
  return calculateArray;
}

var calculate = function(s) {
  s = s.replace(/\s*/g,"");//去除空格
  let num = 0;//当前待运算的数
  let result = 0;//计算结果
  let preSign = "+";//当前需要运算的运算符
  let retCalculateArray = [];
  let calculateArray = toArrayFormula(s);
  //先算乘除
  for (let i = 0; i < calculateArray.length; i++) {
    if (!isNaN(Number(calculateArray[i]))) {
      num = Number(calculateArray[i]);
    }
    if (isNaN(Number(calculateArray[i])) || i === calculateArray.length - 1) {
      switch (preSign) {
        case '+':
          retCalculateArray.push(num);
            break;
        case '-':
          retCalculateArray.push(-num);
            break;
        case '*':
          retCalculateArray.push(retCalculateArray.pop() * num);
            break;
        default:
          retCalculateArray.push(retCalculateArray.pop() / num | 0);
      }
      preSign = calculateArray[i];
    }
  }

  //再算加减
  while (retCalculateArray.length) {
    //@!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    //result += retCalculateArray.shift();//使用shift提交报超时,不明所以,如有大神请留言指教
    result += retCalculateArray.pop();//正确
  }
  return result;
};
// @lc code=end