逆波兰表达式-772基本计算器III

134 阅读1分钟

772. 基本计算器 III

实现一个基本的计算器来计算简单的表达式字符串。

表达式字符串只包含非负整数,算符 +-*/ ,左括号 ( 和右括号 ) 。整数除法需要 向下截断 。

你可以假定给定的表达式总是有效的。所有的中间结果的范围均满足 [-231, 231 - 1] 。

注意: 你不能使用任何将字符串作为表达式求值的内置函数,比如 eval() 。

 

示例 1:

输入: s = "1+1"
输出: 2

示例 2:

输入: s = "6-4/2"
输出: 4

示例 3:

输入: s = "2*(5+5*2)/3+(6/2+8)"
输出: 21

 

提示:

  • 1 <= s <= 104
  • s 由整数、'+''-''*''/''(' 和 ')' 组成
  • s 是一个 有效的 表达式
/**
 * @param {string} s
 * @return {number}
 */
var calculate = function(s) {
  const suffixExpression = []; // 逆波兰表达式
  const stack = []; // 符号栈
  // 符号优先级权重
  const map = {
    '*': 3,
    '/': 3,
    '+': 2,
    '-': 2,
    '(': 1
  }
  let num = 0;
  let preNumFlg = false;
  for (const ch of s) {
    if (isNumber(ch)) {
      num = num * 10 + Number(ch);
      preNumFlg = true;
    } else {
      if (preNumFlg) {
        suffixExpression.push(num);
        num = 0;
        preNumFlg = false;
      }
      if (ch === ' ') {
        continue;
      }

      if (ch === '(') {
        stack.push('(')
      } else if (ch === ')') {
        let cur = stack.pop();
        while (cur !== '(') {
          suffixExpression.push(cur);
          cur = stack.pop();
        }
      } else {
        while (stack.length && map[stack[stack.length - 1]] >= map[ch]) {
          suffixExpression.push(stack.pop());
        }
        stack.push(ch)
      }
      
    }
  }

  if (preNumFlg) {
    suffixExpression.push(num);
  }

  while (stack.length) {
    suffixExpression.push(stack.pop());
  }

  for (const ch of suffixExpression) {
    switch (ch) {
      case '*': {
        const num2 = stack.pop();
        const num1 = stack.pop();
        stack.push(num1 * num2);
        break;
      }
      case '/': {
        const num2 = stack.pop();
        const num1 = stack.pop();
        const result = num1 / num2 < 0 ? Math.ceil(num1 / num2) : Math.floor(num1 / num2);
        stack.push(result);
        break;
      }
      case '+': {
        const num2 = stack.pop();
        const num1 = stack.pop();
        stack.push(num1 + num2);
        break;
      }
      case '-': {
        const num2 = stack.pop();
        const num1 = stack.pop();
        stack.push(num1 - num2);
        break;
      }
      default: {
        stack.push(Number(ch));
      }
    }
  }

  return stack[0];

};

function isNumber(ch) {
  return !isNaN(ch);
}