JS实现基本计算器

656 阅读2分钟

正题

基本计算器 II

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

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

示例 1:

输入:s = "3+2*2"
输出:7

示例 2:

输入:s = " 3/2 "
输出:1

示例 3:

输入:s = " 3+5 / 2 "
输出:5

分析:

基本计算器即是解决 加减乘除 的问题,首先第一个想到的办法就是遍历字符串,那么问题来了,首先要区分是数字还是符号,接着遍历单个字符如果遇到大于10的数怎么处理呢?假设一种情况 34*2,那么遍历的时候我就只会拿到数字3和数字4,如何看成是数字34??

突然想到,如果说有一个栈,将字符串遍历不停讲字符push进栈,那么如果连续push进去的是数字,不就可以得到34了嘛?

所以这题的根本解决思路可能还是要放到栈上。

那么首先解决第一个问题,确认遍历的字符是数字还是符号,这个用正则表达式,判断是否为数字即可,非数字我们就默认为是符号: /\D/.test(char)

其次是运算顺序的问题,先乘除后加减,那么我们可以认为,当栈中出现乘除法的时候可以立即计算,然后将结果直接推入栈中,这样栈中就只剩下加减法,最后再一次计算即可。

1.gif

/**
 * @param {string} s
 * @return {number}
 */
var calculate = function(s) {
  let stack = [], sign = '+', number = ''
  for(let index = 0 ; index < s.length || number; index++) {
      const char = s[index]
      if (char === ' ') continue
      if (/\D/.test(char)) {
          if (sign === '+') {
              stack.push(parseInt(number))
          } else if (sign === '-') {
              stack.push(-parseInt(number))
          } else if (sign === '*') {
              stack.push(stack.pop() * parseInt(number))
          } else {
              stack.push(stack.pop() / parseInt(number) | 0)
          }
          sign = char
          number = ''
      } else {
          number = number + char

      }
  }
  console.log(stack)
  return stack.reduce((p, v) => p + v)
};

主要思路在于

  1. 栈决定执行顺序
  2. 字符拼接成数字包括>10的数字
  3. 将数字暂存,直到出现符号
  4. 如果是非乘除那么直接推入栈,如果是乘除那么先使用暂存的数字计算过后再推入栈
  5. 栈求和