使用C++实现中缀表达式转换到抽象语法树,输出结果以树状图形式展现
时间: 2024-03-16 15:46:50 浏览: 71
C++ 表达式求解 MFC源代码含注释.txt
好的,关于使用C++实现中缀表达式转换到抽象语法树,并以树状图形式展现结果的问题,我可以给您提供一些思路和建议。
1. 实现中缀表达式转换到抽象语法树的算法
中缀表达式转换到抽象语法树的算法可以使用逆波兰表达式求值算法,首先将中缀表达式转换为逆波兰表达式,然后利用栈结构进行求值,最后生成一棵抽象语法树。在生成抽象语法树时,可以使用节点类来表示每个运算符和操作数。
以下是C++代码示例,用于将中缀表达式转换为抽象语法树并以树状图形式展现。
```C++
#include <iostream>
#include <string>
#include <stack>
#include <vector>
#include <algorithm>
#include <sstream>
#include <queue>
#include <fstream>
using namespace std;
struct TreeNode {
char value;
TreeNode* left;
TreeNode* right;
TreeNode(char val): value(val), left(nullptr), right(nullptr){}
};
void display(TreeNode* root) {
if (!root) return;
queue<TreeNode*> q;
q.push(root);
while (!q.empty()) {
int size = q.size();
for (int i = 0; i < size; i++) {
auto node = q.front(); q.pop();
cout << node->value << " ";
if (node->left) q.push(node->left);
if (node->right) q.push(node->right);
}
cout << endl;
}
}
bool isOperator(char c) {
return c == '+' || c == '-' || c == '*' || c == '/';
}
int priority(char op) {
if (op == '+' || op == '-') return 1;
if (op == '*' || op == '/') return 2;
return 0;
}
vector<string> infixToPostfix(string infix) {
vector<string> postfix;
stack<char> opStack;
istringstream iss(infix);
string token;
while (iss >> token) {
if (isdigit(token[0])) {
postfix.push_back(token);
} else if (isOperator(token[0])) {
while (!opStack.empty() && opStack.top() != '(' && priority(token[0]) <= priority(opStack.top())) {
postfix.push_back(string(1, opStack.top()));
opStack.pop();
}
opStack.push(token[0]);
} else if (token[0] == '(') {
opStack.push(token[0]);
} else if (token[0] == ')') {
while (!opStack.empty() && opStack.top() != '(') {
postfix.push_back(string(1, opStack.top()));
opStack.pop();
}
if (!opStack.empty()) opStack.pop();
}
}
while (!opStack.empty()) {
postfix.push_back(string(1, opStack.top()));
opStack.pop();
}
return postfix;
}
TreeNode* buildTree(vector<string>& postfix) {
stack<TreeNode*> st;
for (auto token : postfix) {
if (isdigit(token[0])) {
st.push(new TreeNode(token[0]));
} else if (isOperator(token[0])) {
auto right = st.top(); st.pop();
auto left = st.top(); st.pop();
auto node = new TreeNode(token[0]);
node->left = left;
node->right = right;
st.push(node);
}
}
return st.top();
}
int main() {
string infix = "1 + 2 * 3";
auto postfix = infixToPostfix(infix);
auto root = buildTree(postfix);
display(root);
return 0;
}
```
2. 以树状图形式展现抽象语法树
可以使用Graphviz这样的图形库来实现以树状图形式展现抽象语法树。Graphviz是一个开源的图形可视化软件,可以根据输入的文本描述自动生成图形。在C++程序中,可以使用Graphviz的API来生成抽象语法树的图形,并将其输出到文件中。
以下是C++代码示例,用于将抽象语法树以树状图形式展现。
```C++
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
struct TreeNode {
char value;
TreeNode* left;
TreeNode* right;
TreeNode(char val): value(val), left(nullptr), right(nullptr){}
};
void generateDot(TreeNode* root, ofstream& dotFile) {
if (!root) return;
if (root->left) {
dotFile << root->value << " -> " << root->left->value << endl;
generateDot(root->left, dotFile);
}
if (root->right) {
dotFile << root->value << " -> " << root->right->value << endl;
generateDot(root->right, dotFile);
}
}
void display(TreeNode* root) {
ofstream dotFile("tree.dot");
dotFile << "digraph Tree {" << endl;
generateDot(root, dotFile);
dotFile << "}" << endl;
dotFile.close();
system("dot -Tpng -o tree.png tree.dot");
system("open tree.png");
}
bool isOperator(char c) {
return c == '+' || c == '-' || c == '*' || c == '/';
}
int priority(char op) {
if (op == '+' || op == '-') return 1;
if (op == '*' || op == '/') return 2;
return 0;
}
vector<string> infixToPostfix(string infix) {
vector<string> postfix;
stack<char> opStack;
istringstream iss(infix);
string token;
while (iss >> token) {
if (isdigit(token[0])) {
postfix.push_back(token);
} else if (isOperator(token[0])) {
while (!opStack.empty() && opStack.top() != '(' && priority(token[0]) <= priority(opStack.top())) {
postfix.push_back(string(1, opStack.top()));
opStack.pop();
}
opStack.push(token[0]);
} else if (token[0] == '(') {
opStack.push(token[0]);
} else if (token[0] == ')') {
while (!opStack.empty() && opStack.top() != '(') {
postfix.push_back(string(1, opStack.top()));
opStack.pop();
}
if (!opStack.empty()) opStack.pop();
}
}
while (!opStack.empty()) {
postfix.push_back(string(1, opStack.top()));
opStack.pop();
}
return postfix;
}
TreeNode* buildTree(vector<string>& postfix) {
stack<TreeNode*> st;
for (auto token : postfix) {
if (isdigit(token[0])) {
st.push(new TreeNode(token[0]));
} else if (isOperator(token[0])) {
auto right = st.top(); st.pop();
auto left = st.top(); st.pop();
auto node = new TreeNode(token[0]);
node->left = left;
node->right = right;
st.push(node);
}
}
return st.top();
}
int main() {
string infix = "1 + 2 * 3";
auto postfix = infixToPostfix(infix);
auto root = buildTree(postfix);
display(root);
return 0;
}
```
以上代码实现了将中缀表达式"1 + 2 * 3"转换为抽象语法树,并以树状图形式展示。在这个例子中,我们使用了逆波兰表达式求值算法来生成抽象语法树,使用了Graphviz库来生成树形图形。
阅读全文