【C++】朝花夕拾——表达式树
表达式树:
叶子是操作数,其余结点为操作符,是二叉树的其中一种应用
====================我是分割线======================
一棵表达式树如下图:
若是对它做中序遍历,则可以得到中缀表达式
做后序遍历,则可以得到后缀表达式
已知树的结点可以表示成:
1 struct TreeNode { 2 object element; 3 TreeNode* leftChild; 4 TreeNode* rightChild; 5 };
用后缀表达式构建一棵表达式树:
思路:(与后缀表达式计算四则运算结构相似)
1. 一一读入输入字符串
2. 若是操作数,则初始化为结点后入栈
3. 若是操作符,则从栈中弹出两个结点(新结点的左右子树),与刚读入的操作符结合起来构建新结点,然后入栈
重复1~3,最后栈内有一棵表达式树的root结点
code实现:
1 #include<iostream> 2 #include <string> 3 #include<stack> 4 5 using namespace std; 6 7 struct TreeNode{ 8 char element; 9 TreeNode* leftChild; 10 TreeNode* rightChild; 11 TreeNode(char ch, TreeNode* l, TreeNode* r) { 12 element = ch; 13 leftChild = l; 14 rightChild = r; 15 } 16 TreeNode() { 17 element = '0'; 18 leftChild = 0; 19 rightChild = 0; 20 } 21 }; 22 23 //测试函数——输出树 24 void drawTree(TreeNode* root, bool infix) { 25 if (infix) { 26 if (root) { 27 //中序遍历 28 drawTree(root->leftChild, infix); 29 cout << root->element; 30 drawTree(root->rightChild, infix); 31 } 32 else return; 33 } 34 else { 35 if (root) { 36 //后序遍历 37 drawTree(root->leftChild, infix); 38 drawTree(root->rightChild, infix); 39 cout << root->element; 40 } 41 else return; 42 } 43 } 44 45 int main() { 46 string input; 47 stack<TreeNode> expressionTree; 48 while (cin >> input) { 49 if (input == "0") break; 50 for (int i = 0; i < input.size();) { 51 char ch = input[i++]; 52 if (ch >= '0' && ch <= '9') { 53 TreeNode leaves; 54 leaves.element = ch; 55 expressionTree.push(leaves); 56 } 57 else { 58 //出栈,成为新结点右子树 59 TreeNode* right = new TreeNode(expressionTree.top().element, expressionTree.top().leftChild, expressionTree.top().rightChild); 60 expressionTree.pop(); 61 62 ////出栈,成为新结点左子树 63 TreeNode* left = new TreeNode(expressionTree.top().element, expressionTree.top().leftChild, expressionTree.top().rightChild); 64 expressionTree.pop(); 65 66 //新结点入栈 67 TreeNode leave(ch, left, right); 68 expressionTree.push(leave); 69 } 70 } 71 TreeNode* root = &expressionTree.top(); 72 expressionTree.pop(); 73 drawTree(root, true); 74 } 75 return 0; 76 } 77 78 //NULL 与 0 的概念
局限性:
1. 假设所有输入合法,无空格等非法符号输入
2. 测试输出函数不能还原优先级,12+3* 的表达式树测试输出将是 1+2*3,而并非(1+2)*3,如果需要,可以在结构体中再加上一个优先级判断,若子结点的操作符优先级小于父结点,则输出时子树的表达式需要最后要整体放到一个括号内。
一些bugs:
关于NULL、0 和 nullptr的学习:
1. NULL是宏
2. C中对于NULL的定义为 #define NULL ((void *)0)
3. C++中对于NULL的定义为0
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
4. C++11中对于nullptr的定义
1 const 2 class nullptr_t 3 { 4 public: 5 template<class T> 6 inline operator T*() const 7 { return 0; } 8 9 template<class C, class T> 10 inline operator T C::*() const 11 { return 0; } 12 13 private: 14 void operator&() const; 15 } nullptr = {};
5. 由于C++中的定义,在重载函数时容易出错
1 //NULL 0 nullptr 2 #include <iostream> 3 #include <stdio.h> 4 5 using namespace std; 6 7 int f(void* ptr) { 8 return 2; 9 } 10 11 int f(int num) { 12 return 3; 13 } 14 15 int main() { 16 int result1 = f(0); 17 //int result2 = f(NULL); 18 int result3 = f(nullptr); 19 cout << "result1 = " << result1 << endl; 20 //cout << "result2 = " << result2 << endl; 21 cout << "result3 = " << result3 << endl; 22 return 0; 23 }
当我把17行的注释符去掉时:编译错误
最后运行的结果如下:
说明C++11标准中,nullptr的调用在重载时不会又歧义,而0则会在重载时调用int形参的函数
在C++中,可以的话,尽量用nullptr为空指针赋值
文章推荐:
http://www.cppblog.com/airtrack/archive/2012/09/16/190828.html
转载于:https://www.cnblogs.com/cheermyang/p/5288832.html
【C++】朝花夕拾——表达式树相关推荐
- lambda表达式树
一.定义: 表达式树又称为表达式目录树,以数据形式表示语言级代码.所有的数据都存储在树结构中,每个结点表示一个表达式(Expression). 二.要点: –Lambda表达式的参数类型可以忽略,因为 ...
- 表达式树 java_Linq表达式树编译非平凡的对象常量,并以某种方式引用它们
通常,在编译表达式树时,我会想到不是基元类型或字符串的常量是不可能的 . 但是,这段代码: public class A { public int mint = -1; } public static ...
- c语言后缀表达式构造二叉树,C ++程序为后缀表达式构造表达式树
表达式树基本上是用于表示表达式的二叉树.在表达式树中,节点对应于运算符,每个叶节点对应于操作数.这是一个C ++程序,用于按顺序,前顺序和后顺序遍历为后缀表达式构造一个表达式树. 算法Begin Fu ...
- 程序猿修仙之路--数据结构之你是否真的懂数组? c#socket TCP同步网络通信 用lambda表达式树替代反射 ASP.NET MVC如何做一个简单的非法登录拦截...
程序猿修仙之路--数据结构之你是否真的懂数组? 数据结构 但凡IT江湖侠士,算法与数据结构为必修之课.早有前辈已经明确指出:程序=算法+数据结构 .要想在之后的江湖历练中通关,数据结构必不可少.数据 ...
- Lambda表达式和表达式树
一: Lambda表达式 首先,表达式的类型本身并非委托类型,但它可以通过多种方式隐式或者显式地转换成一个委托实例.匿名函数这个术语同时涵盖了匿名方法和Lambda,很多情况下两者可以使用相互转换原则 ...
- 表达式树 php,Linux_LINQ学习笔记:表达式树,构建查询表达式
本节中, 我们 - phpStudy...
构建查询表达式 本节中, 我们假设我们拥有一个这样的实体类: 1: [Table] public partial class Product 2: 3: { 4: 5: [Column(IsPrima ...
- 表达式树amp;amp;无根树转化为有根树
//将无根树转化为有根树 vector<int>g[maxn]; void read-tree() { int u,v; scanf("%d",&n); for ...
- 干货!表达式树解析框架(3)
最新设计请移步 轻量级表达式树解析框架Faller http://www.cnblogs.com/blqw/p/Faller.html 这应该是年前最后一篇了,接下来的时间就要陪陪老婆孩子了 关于表达 ...
- C#复习笔记(4)--C#3:革新写代码的方式(Lambda表达式和表达式树)
Lambda表达式和表达式树 先放一张委托转换的进化图 看一看到lambda简化了委托的使用. lambda可以隐式的转换成委托或者表达式树.转换成委托的话如下面的代码: Func<string ...
最新文章
- kafka异步推送设置重试_一篇文章了解 Kafka 幂等性的原理及实践
- 人工智能乌托邦 迪拜认为2071年人类应该这样生活!
- python发带附件的中文邮件
- 科大讯飞2位董事同日辞职,联合创始人胡郁发力造芯
- 深度学习核心技术精讲100篇(七十七)-主流推荐引擎技术及优缺点分析
- MAT之PCA:利用PCA(四个主成分的贡献率就才达100%)降维提高测试集辛烷值含量预测准确度并《测试集辛烷值含量预测结果对比》
- 狗蛋(驱动小白)和老王(硬件老司机)关于硬件那点事儿的一次密谈
- 工业级POE交换机技术优势及供电方法详解!
- 前端学习(1646):前端系列实战课程之右下角悬浮功能实现思路
- linux如何脚本监控tps,通过shell脚本监控日志切换频率
- 传相互宝或于6月11日被关停 蚂蚁集团回应:假消息
- C/C++-获取成员变量的指针
- Spring Cloud Netflix之Eureka上篇
- docker容器内安装ifconfig netstat ping vim 等测试工具的方法
- django admin 登陆快速添加验证码功能
- 如何判断一个数为无符号数还是有符号数
- 【转】Google Chrome中顺时针/逆时针滚动圆的含义
- 苹果手机屏幕突然变暗_手机突然屏幕失灵
- 综合布线系统工程中计算机插座的标识符号是,TD是综合布线系统工程中计算机插座的标识符号。...
- FastDNS中修改IP地址