📅  最后修改于: 2023-12-03 15:11:04.801000             🧑  作者: Mango
波兰表达式是一种不常见的表达式书写方式,它把操作符写在操作数之前,比如 (1 + 2)
可以写成 + 1 2
,这种方式更方便计算机处理,因为操作符总是在固定位置。
在C++中,比较常见的计算表达式的方式是中缀表达式,即将操作符放在两个操作数中间,比如 (1 + 2)
,但是我们也可以用栈来实现对波兰表达式的计算。
我们可以用一个栈来保存操作数,遇到操作符则弹出栈顶的两个操作数进行计算,再把结果入栈。
#include <iostream>
#include <stack>
#include <string>
#include <sstream>
#include <vector>
#include <cmath>
using namespace std;
// 判断是否为操作符
bool isOperator(const string& s) {
return s == "+" || s == "-" || s == "*" || s == "/" || s == "^";
}
// 计算表达式
double cal(const string& op, double a, double b) {
if (op == "+") return a + b;
if (op == "-") return a - b;
if (op == "*") return a * b;
if (op == "/") return a / b;
if (op == "^") return pow(a, b);
return 0;
}
// 求解波兰表达式
double evalRPN(const vector<string>& tokens) {
stack<double> nums;
for (const auto& token : tokens) {
if (isOperator(token)) {
double b = nums.top(); nums.pop();
double a = nums.top(); nums.pop();
double res = cal(token, a, b);
nums.push(res);
} else {
double num = atof(token.c_str());
nums.push(num);
}
}
return nums.top();
}
// 将中缀表达式转换成波兰表达式
vector<string> infixToRPN(const string& infix) {
vector<string> res;
stack<string> ops;
istringstream iss(infix);
string token;
while (iss >> token) {
if (isOperator(token)) {
// 优先级高的操作符先处理
while (!ops.empty() && isOperator(ops.top()) && (opPrecedence(token) <= opPrecedence(ops.top()))) {
res.push_back(ops.top()); ops.pop();
}
ops.push(token);
} else if (token == "(") {
ops.push(token);
} else if (token == ")") {
while (ops.top() != "(") {
res.push_back(ops.top()); ops.pop();
}
ops.pop(); // 弹出左括号
} else {
res.push_back(token);
}
}
while (!ops.empty()) {
res.push_back(ops.top()); ops.pop();
}
return res;
}
// 示例代码
int main() {
string infix = "3 + 4 * 2 / (1 - 5)^2";
vector<string> rpn = infixToRPN(infix);
cout << "RPN: ";
for (const auto& token : rpn) {
cout << token << " ";
}
cout << endl;
double res = evalRPN(rpn);
cout << "Result: " << res << endl;
return 0;
}
波兰表达式还有一个对称形式叫做逆波兰表达式,即把操作符放在操作数的后面,比如 (1 + 2)
可以写成 1 2 +
,计算方式和波兰表达式一样,只是先弹出的是右操作数。
在实际使用中,波兰表达式比中缀表达式更利于计算机处理,逆波兰表达式也常被用于计算器和编译器中。