使用C++,实现中缀表达式转换成抽象语法树,输出结果为语法树的样子

时间: 2024-03-17 21:40:48 浏览: 22
下面是使用C++实现中缀表达式转换成抽象语法树的示例代码: ```cpp #include <iostream> #include <stack> using namespace std; // 定义抽象语法树节点结构体 struct ASTNode { char op; // 操作符 int val; // 操作数 ASTNode* left; // 左子树 ASTNode* right; // 右子树 ASTNode(char op, int val) { this->op = op; this->val = val; this->left = nullptr; this->right = nullptr; } }; // 判断是否为操作符 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; } // 中缀表达式转换成抽象语法树 ASTNode* infixToAST(string expr) { stack<ASTNode*> nodeStack; // 节点栈 stack<char> opStack; // 操作符栈 for (int i = 0; i < expr.length(); i++) { char c = expr[i]; if (isdigit(c)) { // 如果是数字,将其转换成操作数节点 int val = c - '0'; while (i + 1 < expr.length() && isdigit(expr[i + 1])) { val = val * 10 + (expr[++i] - '0'); } ASTNode* node = new ASTNode('\0', val); nodeStack.push(node); } else if (isOperator(c)) { // 如果是操作符,将其转换成操作符节点 while (!opStack.empty() && priority(opStack.top()) >= priority(c)) { char op = opStack.top(); opStack.pop(); ASTNode* right = nodeStack.top(); nodeStack.pop(); ASTNode* left = nodeStack.top(); nodeStack.pop(); ASTNode* node = new ASTNode(op, 0); node->left = left; node->right = right; nodeStack.push(node); } opStack.push(c); } else if (c == '(') { // 左括号入栈 opStack.push(c); } else if (c == ')') { // 右括号出栈 while (opStack.top() != '(') { char op = opStack.top(); opStack.pop(); ASTNode* right = nodeStack.top(); nodeStack.pop(); ASTNode* left = nodeStack.top(); nodeStack.pop(); ASTNode* node = new ASTNode(op, 0); node->left = left; node->right = right; nodeStack.push(node); } opStack.pop(); } } // 处理剩余的操作符 while (!opStack.empty()) { char op = opStack.top(); opStack.pop(); ASTNode* right = nodeStack.top(); nodeStack.pop(); ASTNode* left = nodeStack.top(); nodeStack.pop(); ASTNode* node = new ASTNode(op, 0); node->left = left; node->right = right; nodeStack.push(node); } return nodeStack.top(); } // 输出抽象语法树 void printAST(ASTNode* node, int indent = 0) { if (node == nullptr) return; for (int i = 0; i < indent; i++) cout << " "; if (node->op == '\0') { cout << node->val << endl; } else { cout << node->op << endl; printAST(node->left, indent + 2); printAST(node->right, indent + 2); } } int main() { string expr = "3*(4+5)-6/(1+2)"; ASTNode* root = infixToAST(expr); printAST(root); return 0; } ``` 在这个示例中,我们定义了一个ASTNode结构体表示抽象语法树节点,包括操作符、操作数、左子树和右子树四个成员变量。然后,我们使用两个栈分别存储节点和操作符,遍历中缀表达式,根据优先级规则将操作符转换成操作符节点,并将其作为子节点放入其它节点中。最后,我们输出抽象语法树的样子,可以看到它的结构和中缀表达式的结构类似,但更加清晰易懂。

相关推荐

最新推荐

recommend-type

C语言实现中缀表达式转换为后缀表达式

本文实例为大家分享了C语言实现中缀表达式转后缀表达式的具体代码,供大家参考,具体内容如下 中缀表达式转换为后缀表达式(思路) 1.创建栈 2.从左向右顺序获取中缀表达式 a.数字直接输出 b.运算符 情况一:遇到左...
recommend-type

将中缀表达式转换为后缀表达式并求值实验报告

使用键盘输入表达式,计算表达式的值并输出;将表达式转化成后缀表达式输出,利用后缀表达式求表达式的值并输出。
recommend-type

stc芯片制作的定时开关,控制灯光,包含DS1302时钟芯片应用

stc芯片制作的定时开关,控制灯光,包含DS1302时钟芯片应用
recommend-type

zigbee-cluster-library-specification

最新的zigbee-cluster-library-specification说明文档。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

深入了解MATLAB开根号的最新研究和应用:获取开根号领域的最新动态

![matlab开根号](https://www.mathworks.com/discovery/image-segmentation/_jcr_content/mainParsys3/discoverysubsection_1185333930/mainParsys3/image_copy.adapt.full.medium.jpg/1712813808277.jpg) # 1. MATLAB开根号的理论基础 开根号运算在数学和科学计算中无处不在。在MATLAB中,开根号可以通过多种函数实现,包括`sqrt()`和`nthroot()`。`sqrt()`函数用于计算正实数的平方根,而`nt
recommend-type

react的函数组件的使用

React 的函数组件是一种简单的组件类型,用于定义无状态或者只读组件。 它们通常接受一个 props 对象作为参数并返回一个 React 元素。 函数组件的优点是代码简洁、易于测试和重用,并且它们使 React 应用程序的性能更加出色。 您可以使用函数组件来呈现简单的 UI 组件,例如按钮、菜单、标签或其他部件。 您还可以将它们与 React 中的其他组件类型(如类组件或 Hooks)结合使用,以实现更复杂的 UI 交互和功能。
recommend-type

JSBSim Reference Manual

JSBSim参考手册,其中包含JSBSim简介,JSBSim配置文件xml的编写语法,编程手册以及一些应用实例等。其中有部分内容还没有写完,估计有生之年很难看到完整版了,但是内容还是很有参考价值的。
recommend-type

"互动学习:行动中的多样性与论文攻读经历"

多样性她- 事实上SCI NCES你的时间表ECOLEDO C Tora SC和NCESPOUR l’Ingén学习互动,互动学习以行动为中心的强化学习学会互动,互动学习,以行动为中心的强化学习计算机科学博士论文于2021年9月28日在Villeneuve d'Asq公开支持马修·瑟林评审团主席法布里斯·勒菲弗尔阿维尼翁大学教授论文指导奥利维尔·皮耶昆谷歌研究教授:智囊团论文联合主任菲利普·普雷教授,大学。里尔/CRISTAL/因里亚报告员奥利维耶·西格德索邦大学报告员卢多维奇·德诺耶教授,Facebook /索邦大学审查员越南圣迈IMT Atlantic高级讲师邀请弗洛里安·斯特鲁布博士,Deepmind对于那些及时看到自己错误的人...3谢谢你首先,我要感谢我的两位博士生导师Olivier和Philippe。奥利维尔,"站在巨人的肩膀上"这句话对你来说完全有意义了。从科学上讲,你知道在这篇论文的(许多)错误中,你是我可以依
recommend-type

解决MATLAB开根号常见问题:提供开根号运算的解决方案

![解决MATLAB开根号常见问题:提供开根号运算的解决方案](https://img-blog.csdnimg.cn/d939d1781acc404d8c826e8af207e68f.png) # 1. MATLAB开根号运算基础** MATLAB开根号运算用于计算一个数的平方根。其语法为: ``` y = sqrt(x) ``` 其中: * `x`:要开根号的数或数组 * `y`:开根号的结果 开根号运算的输入可以是实数、复数、矩阵或数组。对于实数,开根号运算返回一个非负实数。对于复数,开根号运算返回一个复数。对于矩阵或数组,开根号运算逐元素执行,对每个元素进行开根号运算。 #