js用栈实现计算器
使用栈实现计算器的步骤
利用栈实现计算器需要处理运算符的优先级和括号的匹配。核心思路是通过两个栈(数字栈和运算符栈)来解析表达式,按照运算符优先级进行计算。
初始化栈和优先级映射
创建数字栈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;
}
}
处理表达式字符串
遍历表达式字符串,按字符处理数字、运算符和括号:
- 数字:连续读取数字字符并转换为数值。
- 左括号:直接压入运算符栈。
- 右括号:不断弹出运算符栈直到遇到左括号。
- 运算符:比较优先级并处理栈顶运算。
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
注意事项
- 代码未处理负数输入,需额外处理负号识别。
- 实际应用中需添加输入合法性校验。
- 空格字符需在预处理阶段过滤。







