[路飞]_夜.基本计算器 II

227. 基本计算器 II

题目

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

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

示例1

输入: s = "3+2*2"
输出: 7
复制代码

示例2

输入: s = " 3/2 "
输出: 1
复制代码

解题思路

模拟实现

题目要求只有'+', '-', '*', '/'四则运算,根据四则运算优先级应该先计算乘除,再计算加减

模拟计算过程;

假设有

s = "3+2*2"
复制代码

申请一个空数组list;将数据存放list中;
const list = ['3','+','2','*',2];
第一步:枚举数组list,并将数组list中乘除计算出结果放在原处;

得到: list = ['3','+','4']

第二步:再次枚举数组,将数组中list中加减计算出结果

得到: list = [4];

返回结果即可

根据上述思路编辑代码如下:


var calculate = function (s) {
  const string = s.replace(/^\s+|\s+$/g, '');
  let len = string.length;
  const list = [];
  let t = '';
  for (let i = 0; i < len; i++) {
    const c = string[i];
    if (['+', '-', '*', '/'].includes(c)) {
      list.push(t, c);
      t = '';
    } else {
      t += c;
    }
  }
  if (t) {
    list.push(t);
  }
  //console.log('list', list);

  // 计算乘法;
  len = list.length;
  if (len === 1) return list[0];
  const array = [];
  for (let i = 0; i < len; i++) {
    const t = array[array.length - 1];
    if (t === '*') {
      array.pop();
      const after = array.pop();
      const n = after * list[i];
      array.push(n);
    } else if (t === '/') {
      array.pop();
      const after = array.pop();
      const n = Math.floor(after / list[i]);
      array.push(n);
    } else {
      array.push(list[i]);
    }
  }

  let result = 0;
  let sign = 1;
  for (let i = 0; i < array.length; i++) {
    const n = array[i];
    if (n === '+') {
      sign = 1;
    }
    if (n === '-') {
      sign = -1;
    }
    if (!['+', '-'].includes(n)) {
      result += sign * n;
    }
  }
  return Math.floor(result);
};
复制代码

上述思路虽然没错,但是代码写起来太繁琐了;需要一遍一遍的遍历数组;先计算乘除,后计算加减;能不能优化一下代码呢?

当然可以:

优化后代码如下:

优化了乘除,在第一次枚举字符串时,同时进行乘除操作,将乘除后的结果放在数组中;再次枚举数组只需对数据求和即可得到答案


var calculate = function(s) {
    s = s.trim();
    const stack = new Array();
    let preSign = '+';
    let num = 0;
    const n = s.length;
    for (let i = 0; i < n; ++i) {
        if (!isNaN(Number(s[i])) && s[i] !== ' ') {
            num = num * 10 + s[i].charCodeAt() - '0'.charCodeAt();
        }
        if (isNaN(Number(s[i])) || i === n - 1) {
            switch (preSign) {
                case '+':
                    stack.push(num);
                    break;
                case '-':
                    stack.push(-num);
                    break;
                case '*':
                    stack.push(stack.pop() * num);
                    break;
                default:
                    stack.push(stack.pop() / num | 0);
            }   
            preSign = s[i];
            num = 0;
        }
    }
    let ans = 0;
    while (stack.length) {
        ans += stack.pop();
    }
    return ans;
};
复制代码

猜你喜欢

转载自juejin.im/post/7033392987233222687