【C++】朝花夕拾——表达式树
表达式树:
叶子是操作数,其余结点为操作符,是二叉树的其中一种应用
====================我是分割线======================
一棵表达式树如下图:
若是对它做中序遍历,则可以得到中缀表达式
做后序遍历,则可以得到后缀表达式
已知树的结点可以表示成:
struct TreeNode {
object element;
TreeNode* leftChild;
TreeNode* rightChild;
};
用后缀表达式构建一棵表达式树:
思路:(与后缀表达式计算四则运算结构相似)
1. 一一读入输入字符串
2. 若是操作数,则初始化为结点后入栈
3. 若是操作符,则从栈中弹出两个结点(新结点的左右子树),与刚读入的操作符结合起来构建新结点,然后入栈
重复1~3,最后栈内有一棵表达式树的root结点
code实现:
#include<iostream>
#include <string>
#include<stack> using namespace std; struct TreeNode{
char element;
TreeNode* leftChild;
TreeNode* rightChild;
TreeNode(char ch, TreeNode* l, TreeNode* r) {
element = ch;
leftChild = l;
rightChild = r;
}
TreeNode() {
element = '';
leftChild = ;
rightChild = ;
}
}; //测试函数——输出树
void drawTree(TreeNode* root, bool infix) {
if (infix) {
if (root) {
//中序遍历
drawTree(root->leftChild, infix);
cout << root->element;
drawTree(root->rightChild, infix);
}
else return;
}
else {
if (root) {
//后序遍历
drawTree(root->leftChild, infix);
drawTree(root->rightChild, infix);
cout << root->element;
}
else return;
}
} int main() {
string input;
stack<TreeNode> expressionTree;
while (cin >> input) {
if (input == "") break;
for (int i = ; i < input.size();) {
char ch = input[i++];
if (ch >= '' && ch <= '') {
TreeNode leaves;
leaves.element = ch;
expressionTree.push(leaves);
}
else {
//出栈,成为新结点右子树
TreeNode* right = new TreeNode(expressionTree.top().element, expressionTree.top().leftChild, expressionTree.top().rightChild);
expressionTree.pop(); ////出栈,成为新结点左子树
TreeNode* left = new TreeNode(expressionTree.top().element, expressionTree.top().leftChild, expressionTree.top().rightChild);
expressionTree.pop(); //新结点入栈
TreeNode leave(ch, left, right);
expressionTree.push(leave);
}
}
TreeNode* root = &expressionTree.top();
expressionTree.pop();
drawTree(root, true);
}
return ;
} //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的定义
const
class nullptr_t
{
public:
template<class T>
inline operator T*() const
{ return ; } template<class C, class T>
inline operator T C::*() const
{ return ; } private:
void operator&() const;
} nullptr = {};
5. 由于C++中的定义,在重载函数时容易出错
//NULL 0 nullptr
#include <iostream>
#include <stdio.h> using namespace std; int f(void* ptr) {
return ;
} int f(int num) {
return ;
} int main() {
int result1 = f();
//int result2 = f(NULL);
int result3 = f(nullptr);
cout << "result1 = " << result1 << endl;
//cout << "result2 = " << result2 << endl;
cout << "result3 = " << result3 << endl;
return ;
}
当我把17行的注释符去掉时:编译错误
最后运行的结果如下:
说明C++11标准中,nullptr的调用在重载时不会又歧义,而0则会在重载时调用int形参的函数
在C++中,可以的话,尽量用nullptr为空指针赋值
文章推荐:
http://www.cppblog.com/airtrack/archive/2012/09/16/190828.html
【C++】朝花夕拾——表达式树的更多相关文章
- 再讲IQueryable<T>,揭开表达式树的神秘面纱
接上篇<先说IEnumerable,我们每天用的foreach你真的懂它吗?> 最近园子里定制自己的orm那是一个风生水起,感觉不整个自己的orm都不好意思继续混博客园了(开个玩笑).那么 ...
- [C#] C# 知识回顾 - 表达式树 Expression Trees
C# 知识回顾 - 表达式树 Expression Trees 目录 简介 Lambda 表达式创建表达式树 API 创建表达式树 解析表达式树 表达式树的永久性 编译表达式树 执行表达式树 修改表达 ...
- 轻量级表达式树解析框架Faller
有话说 之前我写了3篇关于表达式树解析的文章 干货!表达式树解析"框架"(1) 干货!表达式树解析"框架"(2) 干货!表达式树解析"框架" ...
- 用五分钟重温委托,匿名方法,Lambda,泛型委托,表达式树
这些对老一代的程序员都是老生常谈的东西,没什么新意,对新生代的程序员却充满着魅力.曾经新生代,好多都经过漫长的学习,理解,实践才能掌握委托,表达式树这些应用.今天我尝试用简单的方法叙述一下,让大家在五 ...
- LinqToDB 源码分析——处理表达式树
处理表达式树可以说是所有要实现Linq To SQL的重点,同时他也是难点.笔者看完作者在LinqToDB框架里面对于这一部分的设计之后,心里有一点不知所然.由于很多代码没有文字注解.所以笔者只能接合 ...
- LinqToDB 源码分析——生成表达式树
当我们知道了Linq查询要用到的数据库信息之后.接下就是生成对应的表达式树.在前面的章节里面笔者就已经介绍过.生成表达式树是事实离不开IQueryable<T>接口.而处理表达式树离不开I ...
- 干货!表达式树解析"框架"(1)
最新设计请移步 轻量级表达式树解析框架Faller http://www.cnblogs.com/blqw/p/Faller.html 关于我和表达式树 其实我也没有深入了解表达式树一些内在实现的原理 ...
- 干货!表达式树解析"框架"(2)
最新设计请移步 轻量级表达式树解析框架Faller http://www.cnblogs.com/blqw/p/Faller.html 为了过个好年,我还是赶快把这篇完成了吧 声明 本文内容需要有一定 ...
- 干货!表达式树解析"框架"(3)
最新设计请移步 轻量级表达式树解析框架Faller http://www.cnblogs.com/blqw/p/Faller.html 这应该是年前最后一篇了,接下来的时间就要陪陪老婆孩子了 关于表达 ...
随机推荐
- YTU 2837: 编程题B-狐狸算卦
2837: 编程题B-狐狸算卦 时间限制: 1 Sec 内存限制: 128 MB 提交: 76 解决: 52 题目描述 注:本题只需要提交需要完善部分的代码,请按照C++方式提交. 小熊和狐狸是邻 ...
- evm指令集手册
evm指令集手册 Opcodes 结果列为"-"表示没有运算结果(不会在栈上产生值),为"*"是特殊情况,其他都表示运算产生唯一值,并放在栈顶. mem[a.. ...
- javascript来实现详细时间提醒信息效果
我们经常在社交网络上面看到很人性化的时间提示比如,你的朋友几分钟前更新了什么,你的朋友几天前更新了什么信息. 这些小tips比直接显示某年某月人性化很多.我们可以用不同的程序实现这种效果.中国音效网下 ...
- 揭开自然拼读法(Phonics)的神秘面纱
揭开自然拼读法(Phonics)的神秘面纱 自然拼读法 (Phonics),是指看到一个单词,就可以根据英文字母在单词里的发音规律把这个单词读出来的一种方法.即从“字母发音-字母组合发音-单词-简单 ...
- mac系统下命令编译android ndk项目
1.设置ndk环境变量 2.构造android ndk项目,命令:ndk-build 3.使用ant构造android sdk项目:命令:android update project -p . -n ...
- 并不对劲的bzoj2820:p2257:YY的GCD
题目大意 \(t\)(\(t\leq10^4\))组数据,给定\(n,m\)(\(n,m\leq10^6\))求 \[\sum_{x=1}^{n}\sum_{y=1}^{m}[gcd(x,y)=1]\ ...
- 并不对劲的bzoj3626:loj2558:p4211:[LNOI2014]LCA
题目大意 有一棵有\(n\)(\(n\leq5*10^4\))个点的树,\(q\)(\(q\leq5*10^4\))次询问,每次给出\(l,r,x\)表示询问所有编号在\([l,r]\)的点与点\(x ...
- 查看html元素绑定的事件与方法 visual Event 插件
WEB标准提倡结构.表现和行为相 分离,现在越来越多采用这种表现和行为的方式,但它也为我们开发调试带来一些问题,网页载入一堆JavaScript,,我们很难搞清楚最后在哪些元素的哪个动作绑定了事件,尤 ...
- Bootstrap 垂直(默认)表单
在建立asp.net mvc视图中,默认的表单是垂直表单,与vs 自动创建的T4模板是水平表单,相比较,没有了<div class="form-horizontal"> ...
- ubuntu 12.04 alt+tab无法切换窗口的问题(转载)
转自:http://www.2cto.com/os/201209/153282.html ubuntu 12.04 alt+tab无法切换窗口的问题 安装cpmpiz配置管理程序. sudo ...