C++中的前缀表达式,中缀表达式,后缀表达式
·
前缀表达式(波兰表达式)
前缀表达式的运算符位于操作数之前,不需要括号来定义运算顺序,运算顺序完全由运算符的位置决定。例如,+ 3 4 等价于中缀表达式的 3 + 4。
-
示例:
+ * 3 4 5等价于中缀的(3 * 4) + 5。- + 1 2 * 3 4等价于中缀的(1 + 2) - (3 * 4)。
-
计算方法: 从右向左扫描表达式,遇到操作数压栈,遇到运算符弹出栈顶两个操作数计算,并将结果压栈。
#include <stack>
#include <string>
#include <sstream>
using namespace std;
int evaluatePrefix(const string& expr) {
stack<int> st;
istringstream iss(expr);
string token;
while (iss >> token) {
if (isdigit(token[0])) {
st.push(stoi(token));
} else {
int a = st.top(); st.pop();
int b = st.top(); st.pop();
if (token == "+") st.push(a + b);
else if (token == "-") st.push(a - b);
else if (token == "*") st.push(a * b);
else if (token == "/") st.push(a / b);
}
}
return st.top();
}
中缀表达式
中缀表达式是常见的数学表达式形式,运算符位于操作数之间,例如 3 + 4 * 5。中缀表达式需要括号或优先级规则来明确运算顺序。
-
示例:
3 + 4 * 5的运算顺序是3 + (4 * 5)。(3 + 4) * 5的运算顺序是(3 + 4) * 5。
-
计算方法: 通常需要转换为前缀或后缀表达式后再计算,或使用双栈法(操作数栈和运算符栈)直接求值。
#include <stack>
#include <string>
#include <cctype>
using namespace std;
int evaluateInfix(const string& expr) {
stack<int> nums;
stack<char> ops;
for (int i = 0; i < expr.size(); ++i) {
if (expr[i] == ' ') continue;
if (isdigit(expr[i])) {
int num = 0;
while (i < expr.size() && isdigit(expr[i])) {
num = num * 10 + (expr[i] - '0');
++i;
}
--i;
nums.push(num);
} else if (expr[i] == '(') {
ops.push(expr[i]);
} else if (expr[i] == ')') {
while (ops.top() != '(') {
char op = ops.top(); ops.pop();
int b = nums.top(); nums.pop();
int a = nums.top(); nums.pop();
if (op == '+') nums.push(a + b);
else if (op == '-') nums.push(a - b);
else if (op == '*') nums.push(a * b);
else if (op == '/') nums.push(a / b);
}
ops.pop();
} else {
while (!ops.empty() && ops.top() != '(' &&
((expr[i] == '+' || expr[i] == '-') &&
(ops.top() == '*' || ops.top() == '/'))) {
char op = ops.top(); ops.pop();
int b = nums.top(); nums.pop();
int a = nums.top(); nums.pop();
if (op == '+') nums.push(a + b);
else if (op == '-') nums.push(a - b);
else if (op == '*') nums.push(a * b);
else if (op == '/') nums.push(a / b);
}
ops.push(expr[i]);
}
}
while (!ops.empty()) {
char op = ops.top(); ops.pop();
int b = nums.top(); nums.pop();
int a = nums.top(); nums.pop();
if (op == '+') nums.push(a + b);
else if (op == '-') nums.push(a - b);
else if (op == '*') nums.push(a * b);
else if (op == '/') nums.push(a / b);
}
return nums.top();
}
后缀表达式(逆波兰表达式)
后缀表达式的运算符位于操作数之后,例如 3 4 + 等价于中缀的 3 + 4。后缀表达式无需括号,运算顺序由运算符位置决定。
-
示例:
3 4 * 5 +等价于中缀的(3 * 4) + 5。1 2 + 3 4 * -等价于中缀的(1 + 2) - (3 * 4)。
-
计算方法: 从左向右扫描表达式,遇到操作数压栈,遇到运算符弹出栈顶两个操作数计算,并将结果压栈。
#include <stack>
#include <string>
#include <sstream>
using namespace std;
int evaluatePostfix(const string& expr) {
stack<int> st;
istringstream iss(expr);
string token;
while (iss >> token) {
if (isdigit(token[0])) {
st.push(stoi(token));
} else {
int b = st.top(); st.pop();
int a = st.top(); st.pop();
if (token == "+") st.push(a + b);
else if (token == "-") st.push(a - b);
else if (token == "*") st.push(a * b);
else if (token == "/") st.push(a / b);
}
}
return st.top();
}
转换方法
中缀表达式可以转换为前缀或后缀表达式,常用方法包括:
- 中缀转后缀:使用栈处理运算符优先级,输出操作数并调整运算符顺序。
- 中缀转前缀:从右向左扫描中缀表达式,使用栈处理运算符优先级。
转换算法的核心是通过栈管理运算符优先级和括号匹配。
更多推荐


所有评论(0)