当前位置:首页 > JavaScript

js用栈实现计算器

2026-03-02 01:28:58JavaScript

使用栈实现计算器的思路

利用栈可以高效处理表达式中的运算符优先级和括号嵌套问题。核心思路是将中缀表达式转换为后缀表达式(逆波兰表达式),再通过栈计算后缀表达式的值。

中缀转后缀的算法步骤

初始化一个运算符栈和一个输出队列(或数组)。从左到右扫描中缀表达式:

遇到数字时直接加入输出队列。

遇到运算符时:

  • 若栈顶运算符优先级不低于当前运算符,弹出栈顶运算符并加入输出队列
  • 将当前运算符压入栈中

遇到左括号时直接压入栈中。

遇到右括号时:

  • 弹出栈顶运算符并加入输出队列,直到遇到左括号
  • 弹出左括号但不输出

计算后缀表达式的算法

初始化一个操作数栈。从左到右扫描后缀表达式:

遇到数字时压入操作数栈。

遇到运算符时:

  • 弹出栈顶两个数字
  • 按运算符计算(注意操作数顺序)
  • 将结果压回栈中

JavaScript实现代码

class Stack {
  constructor() {
    this.items = []
  }
  push(element) {
    this.items.push(element)
  }
  pop() {
    return this.items.pop()
  }
  peek() {
    return this.items[this.items.length - 1]
  }
  isEmpty() {
    return this.items.length === 0
  }
}

function infixToPostfix(infix) {
  const precedence = {'+':1, '-':1, '*':2, '/':2, '^':3}
  const stack = new Stack()
  let postfix = []

  for(let token of infix.match(/(\d+|\+|\-|\*|\/|\^|\(|\))/g)) {
    if(/\d+/.test(token)) {
      postfix.push(token)
    } else if(token === '(') {
      stack.push(token)
    } else if(token === ')') {
      while(stack.peek() !== '(') {
        postfix.push(stack.pop())
      }
      stack.pop() // 弹出左括号
    } else {
      while(!stack.isEmpty() && stack.peek() !== '(' && 
            precedence[stack.peek()] >= precedence[token]) {
        postfix.push(stack.pop())
      }
      stack.push(token)
    }
  }

  while(!stack.isEmpty()) {
    postfix.push(stack.pop())
  }

  return postfix
}

function evaluatePostfix(postfix) {
  const stack = new Stack()

  for(let token of postfix) {
    if(/\d+/.test(token)) {
      stack.push(parseFloat(token))
    } else {
      const b = stack.pop()
      const a = stack.pop()
      switch(token) {
        case '+': stack.push(a + b); break
        case '-': stack.push(a - b); break
        case '*': stack.push(a * b); break
        case '/': stack.push(a / b); break
        case '^': stack.push(Math.pow(a, b)); break
      }
    }
  }

  return stack.pop()
}

// 使用示例
const infix = "3+4*2/(1-5)^2"
const postfix = infixToPostfix(infix)
const result = evaluatePostfix(postfix)
console.log(result) // 输出3.5

处理负数的扩展

上述实现不支持负数开头表达式,需预处理:

function preprocessInfix(infix) {
  // 将"-"替换为"0-"当它是表达式开头或跟在"("后
  return infix.replace(/(^|\(|\+|\-|\*|\/|\^)\s*\-/g, '$10-')
}

// 使用示例
const infix = "-3+4*(-2)"
const processed = preprocessInfix(infix)
const postfix = infixToPostfix(processed)
const result = evaluatePostfix(postfix)
console.log(result) // 输出-11

注意事项

运算符优先级定义影响计算结果,需根据需求调整。

对于浮点数运算,需考虑精度问题,可使用toFixed等方法处理。

大数运算可能需要使用BigInt或其他大数库。

js用栈实现计算器

标签: 计算器js
分享给朋友:

相关文章

js实现vue

js实现vue

Vue.js 简介 Vue.js 是一个渐进式 JavaScript 框架,用于构建用户界面。其核心库专注于视图层,易于与其他库或现有项目整合。 实现 Vue.js 的基本步骤 安装 Vue.j…

js实现类

js实现类

JavaScript 实现类的几种方式 JavaScript 是一种基于原型的语言,但在 ES6 之后引入了 class 语法糖,使得实现类更加直观。以下是几种常见的实现方式: 使用构造函数 传统…

js实现拷贝

js实现拷贝

实现文本拷贝 使用 document.execCommand 方法(已废弃但兼容性较好): function copyText(text) { const textarea = document…

js实现vr

js实现vr

使用WebXR API实现VR体验 WebXR是浏览器中实现VR和AR体验的标准API,它取代了早期的WebVR。现代浏览器如Chrome、Edge和Firefox已支持WebXR。 // 初始化W…

js实现抽奖

js实现抽奖

实现抽奖功能的基本思路 抽奖功能的核心是随机选择奖项并展示结果。可以通过数组存储奖项,利用随机数生成索引,最后通过动画增强用户体验。 准备奖项数据 定义一个数组存储奖项信息,每个奖项可以包含名称、…

js实现祖玛

js实现祖玛

实现祖玛游戏的核心思路 祖玛游戏的核心玩法是发射彩色珠子,形成三个或以上相同颜色的珠子即可消除。以下是使用JavaScript实现的基本框架。 游戏初始化 创建画布并初始化游戏状态: cons…