在编程中,前缀、中缀和后缀表达式是用于描述算术表达式的不同表示方法,主要用于解析和计算数学公式。这些概念在算法设计(尤其是表达式树和栈的应用)中非常重要。下面我将分别解释这三种表达式,并用JavaScript代码示例来说明如何转换和计算它们。
1. 中缀表达式 (Infix Expression)
这是最常见的表达式形式,我们在日常书写数学公式时使用的就是中缀表达式。例如,(3 + 4) * 2
。在这种表示法中,操作符位于其操作数之间。
2. 前缀表达式 (Prefix Expression)
也称为波兰表示法(Polish Notation),在这种表示法中,操作符位于其操作数之前。上述中缀表达式对应的前缀表达式为 * + 3 4 2
。
3. 后缀表达式 (Postfix Expression)
又称逆波兰表示法(Reverse Polish Notation, RPN),操作符位于其操作数之后。同样的例子,后缀表达式为 3 4 + 2 *
。
JavaScript 示例代码
计算后缀表达式
计算后缀表达式相对直接,可以利用栈的数据结构来实现。
function evaluatePostfix(expr) {
let stack = [];
for(let char of expr.split(' ')) {
if(!isNaN(char)) { // 如果是数字,则入栈
stack.push(Number(char));
} else { // 如果是操作符,则出栈两个元素进行运算,然后结果入栈
let b = stack.pop();
let a = stack.pop();
switch(char) {
case '+': stack.push(a + b); break;
case '-': stack.push(a - b); break;
case '*': stack.push(a * b); break;
case '/': stack.push(a / b); break;
}
}
}
return stack.pop(); // 最终栈内只剩一个元素,即为计算结果
}
// 示例
let postfixExpr = "3 4 + 2 *";
console.log(evaluatePostfix(postfixExpr)); // 输出结果应为 14
中缀转后缀表达式
转换中缀表达式为后缀表达式稍微复杂一些,同样需要用到栈。
function infixToPostfix(infix) {
let prec = { // 定义操作符优先级
'+': 1, '-': 1,
'*': 2, '/': 2,
'^': 3
};
let opStack = [], postfix = [];
infix = infix.replace(/\s+/g, '').split('');
for(let char of infix) {
if(!isNaN(char)) { // 数字直接加入输出
postfix.push(char);
} else if(char === '(') { // 左括号入栈
opStack.push(char);
} else if(char === ')') { // 遇到右括号,弹出并输出直到遇到左括号
while(opStack[opStack.length - 1] !== '(') {
postfix.push(opStack.pop());
}
opStack.pop(); // 弹出左括号
} else if(prec[char]) { // 遇到操作符
while(opStack.length && prec[opStack[opStack.length - 1]] >= prec[char]) {
postfix.push(opStack.pop());
}
opStack.push(char);
}
}
while(opStack.length) { // 处理剩余的操作符
postfix.push(opStack.pop());
}
return postfix.join(' ');
}
// 示例
let infixExpr = "( 3 + 4 ) * 2";
console.log(infixToPostfix(infixExpr)); // 输出 "3 4 + 2 *"