当前位置:首页 > JavaScript

js用栈实现计算器

2026-01-31 10:14:16JavaScript

使用栈实现计算器的步骤

利用栈实现计算器需要处理运算符的优先级和括号的匹配。核心思路是通过两个栈(数字栈和运算符栈)来解析表达式,按照运算符优先级进行计算。

初始化栈和优先级映射

创建数字栈numStack和运算符栈opStack,并定义运算符的优先级映射:

const priority = {
    '+': 1,
    '-': 1,
    '*': 2,
    '/': 2,
    '^': 3
};

处理运算符优先级

当遇到新运算符时,比较其与栈顶运算符的优先级。若栈顶优先级更高或相等,则先计算栈顶运算:

function processStack() {
    const b = numStack.pop();
    const a = numStack.pop();
    const op = opStack.pop();
    switch (op) {
        case '+': numStack.push(a + b); break;
        case '-': numStack.push(a - b); break;
        case '*': numStack.push(a * b); break;
        case '/': numStack.push(a / b); break;
        case '^': numStack.push(Math.pow(a, b)); break;
    }
}

处理表达式字符串

遍历表达式字符串,按字符处理数字、运算符和括号:

  1. 数字:连续读取数字字符并转换为数值。
  2. 左括号:直接压入运算符栈。
  3. 右括号:不断弹出运算符栈直到遇到左括号。
  4. 运算符:比较优先级并处理栈顶运算。
let i = 0;
while (i < s.length) {
    if (/\d/.test(s[i])) {
        let num = 0;
        while (i < s.length && /\d/.test(s[i])) {
            num = num * 10 + parseInt(s[i++]);
        }
        numStack.push(num);
    } else if (s[i] === '(') {
        opStack.push(s[i++]);
    } else if (s[i] === ')') {
        while (opStack[opStack.length - 1] !== '(') {
            processStack();
        }
        opStack.pop();
        i++;
    } else {
        while (opStack.length && priority[opStack[opStack.length - 1]] >= priority[s[i]]) {
            processStack();
        }
        opStack.push(s[i++]);
    }
}

完成剩余运算

表达式遍历完成后,若运算符栈非空,继续处理剩余运算:

while (opStack.length) {
    processStack();
}
return numStack.pop();

完整代码示例

function calculate(s) {
    const numStack = [];
    const opStack = [];
    const priority = { '+': 1, '-': 1, '*': 2, '/': 2, '^': 3 };

    function processStack() {
        const b = numStack.pop();
        const a = numStack.pop();
        const op = opStack.pop();
        switch (op) {
            case '+': numStack.push(a + b); break;
            case '-': numStack.push(a - b); break;
            case '*': numStack.push(a * b); break;
            case '/': numStack.push(a / b); break;
            case '^': numStack.push(Math.pow(a, b)); break;
        }
    }

    let i = 0;
    while (i < s.length) {
        if (/\d/.test(s[i])) {
            let num = 0;
            while (i < s.length && /\d/.test(s[i])) {
                num = num * 10 + parseInt(s[i++]);
            }
            numStack.push(num);
        } else if (s[i] === '(') {
            opStack.push(s[i++]);
        } else if (s[i] === ')') {
            while (opStack[opStack.length - 1] !== '(') {
                processStack();
            }
            opStack.pop();
            i++;
        } else {
            while (opStack.length && priority[opStack[opStack.length - 1]] >= priority[s[i]]) {
                processStack();
            }
            opStack.push(s[i++]);
        }
    }

    while (opStack.length) {
        processStack();
    }
    return numStack.pop();
}

测试用例

console.log(calculate("3+2*2"));    // 输出 7
console.log(calculate("(1+2)*3"));  // 输出 9
console.log(calculate("2^3+1"));    // 输出 9

注意事项

  • 代码未处理负数输入,需额外处理负号识别。
  • 实际应用中需添加输入合法性校验。
  • 空格字符需在预处理阶段过滤。

js用栈实现计算器

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

相关文章

js实现倒计时

js实现倒计时

实现倒计时的基本方法 使用 JavaScript 实现倒计时功能可以通过 setInterval 或 setTimeout 结合日期计算来完成。以下是几种常见的实现方式: 使用 setInterv…

js实现继承

js实现继承

原型链继承 通过将子类的原型指向父类的实例实现继承。子类实例可以访问父类原型上的属性和方法。 function Parent() { this.name = 'parent'; } Paren…

js 实现倒计时

js 实现倒计时

实现倒计时的基本方法 使用 JavaScript 实现倒计时可以通过 setInterval 或 setTimeout 结合日期计算来完成。以下是两种常见实现方式。 使用 setInterval 实…

js实现选项卡

js实现选项卡

实现选项卡的基本思路 选项卡通常由一组标签和对应的内容面板组成。点击标签时,显示对应的内容面板,隐藏其他面板。实现这一效果需要结合HTML结构、CSS样式和JavaScript交互逻辑。 HTML结…

js如何实现继承

js如何实现继承

原型链继承 通过将子类的原型指向父类的实例实现继承。子类实例能够访问父类原型上的属性和方法。 function Parent() { this.name = 'parent'; } Parent…

js实现拷贝

js实现拷贝

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