2018-07-21 16:57:26 update

  建立表达式树的基本思路:方法类似由下而上建立堆的思想,所以时间复杂度为O(n),这样算法就会变得很简单,只用考虑处理需要入栈的节点和栈中的节点即可。。。

  code:

#include "stdafx.h"
#include <iostream>
#include <stack>
#include <string> class expr_tree
{
struct base_node
{
char c;
base_node * lc, *rc;
base_node() {}
base_node(char c)
: c(c)
, lc(nullptr)
, rc(nullptr)
{
}
} * root;
protected:
void parse_expr(std::string str);
void proorder_print(base_node * n);
void inorder_print(base_node * n);
void postorder_print(base_node * n);
void destory(base_node * & n);
double eval(base_node * n); public:
void show(); expr_tree(std::string str)
{
parse_expr(str);
}
~expr_tree()
{
destory(this->root);
}
}; void expr_tree::parse_expr(std::string str)
{
std::stack<base_node *> stack_node;
for (auto c : str)
{
base_node * node = new base_node(c);
if (c >= '0' && c <= '9' || c >= 'a' && c <= 'z')
stack_node.push(node);
else if (c == '+' || c == '-' || c == '*' || c == '/')
{
if (!stack_node.empty())
{
node->rc = stack_node.top();
stack_node.pop();
}
if (!stack_node.empty())
{
node->lc = stack_node.top();
stack_node.pop();
}
stack_node.push(node);
}
else
{
std::cout << "表达式有误!" << std::endl;
exit(1);
}
}
root = stack_node.top();
while (!stack_node.empty())
stack_node.pop();
} void expr_tree::proorder_print(base_node * n)
{
if (n)
{
std::cout << n->c;
proorder_print(n->lc);
proorder_print(n->rc);
}
} void expr_tree::inorder_print(base_node * n)
{
if (n)
{
if (n->c >= '0' && n->c <= '9')
std::cout << n->c;
else
{
std::cout << '(';
inorder_print(n->lc);
std::cout << ' ' << n->c << ' ';
inorder_print(n->rc);
std::cout << ')';
}
}
} void expr_tree::postorder_print(base_node * n)
{
if (n)
{
postorder_print(n->lc);
postorder_print(n->rc);
std::cout << n->c;
}
} void expr_tree::show()
{
std::cout << "前缀表达式:" << std::endl;
proorder_print(this->root);
std::cout << std::endl;
std::cout << "中缀表达式:" << std::endl;
inorder_print(this->root);
std::cout << " = " << eval(this->root) << std::endl;
std::cout << "后缀表达式:" << std::endl;
postorder_print(this->root);
std::cout << std::endl;
} double expr_tree::eval(base_node * n)
{
switch (n->c)
{
case '+': return eval(n->lc) + eval(n->rc);
case '-': return eval(n->lc) - eval(n->rc);
case '*': return eval(n->lc) * eval(n->rc);
case '/': return eval(n->lc) / eval(n->rc);
default: return n->c - '0';
}
} void expr_tree::destory(base_node * & root)
{
if (root != nullptr)
{
destory(root->lc);
destory(root->rc);
delete root;
}
} int main()
{
std::string str = "23+456+**"; expr_tree res(str);
res.show();
return 0;
}

  

  

  

C++ — 后缀表达式转表达式树的更多相关文章

  1. [.net 面向对象程序设计进阶] (6) Lamda表达式(二) 表达式树快速入门

    [.net 面向对象程序设计进阶] (6) Lamda表达式(二) 表达式树快速入门 本节导读: 认识表达式树(Expression Tree),学习使用Lambda创建表达式树,解析表达式树. 学习 ...

  2. [.net 面向对象程序设计进阶] (7) Lamda表达式(三) 表达式树高级应用

    [.net 面向对象程序设计进阶] (7) Lamda表达式(三) 表达式树高级应用 本节导读:讨论了表达式树的定义和解析之后,我们知道了表达式树就是并非可执行代码,而是将表达式对象化后的数据结构.是 ...

  3. C#中的Lambda表达式和表达式树

    在C# 2.0中,通过方法组转换和匿名方法,使委托的实现得到了极大的简化.但是,匿名方法仍然有些臃肿,而且当代码中充满了匿名方法的时候,可读性可能就会受到影响.C# 3.0中出现的Lambda表达式在 ...

  4. 16.C#初见Lambda表达式及表达式树(九章9.1-9.3)

    在说明Lambda相关知识前,我们需要了解Lambda表达式常用于LINQ,那么我们来聊下LINQ. LINQ的基本功能就是创建操作管道,以及这些操作需要的任何状态.这些操作表示了各种关于数据的逻辑: ...

  5. Lambda表达式和表达式树

    在C# 2.0中,通过方法组转换和匿名方法,使委托的实现得到了极大的简化.但是,匿名方法仍然有些臃肿,而且当代码中充满了匿名方法的时候,可读性可能就会受到影响.C# 3.0中出现的Lambda表达式在 ...

  6. C#3.0 Lamdba表达式与表达式树

    Lamdba表达式与表达式树 Lamdba表达式 C#2.0中的匿名方法使得创建委托变得简单起来,甚至想不到还有什么方式可以更加的简化,而C#3.0中的lamdba则给了我们答案. lamdba的行为 ...

  7. C#复习笔记(4)--C#3:革新写代码的方式(Lambda表达式和表达式树)

    Lambda表达式和表达式树 先放一张委托转换的进化图 看一看到lambda简化了委托的使用. lambda可以隐式的转换成委托或者表达式树.转换成委托的话如下面的代码: Func<string ...

  8. 深入学习C#匿名函数、委托、Lambda表达式、表达式树类型——Expression tree types

    匿名函数 匿名函数(Anonymous Function)是表示“内联”方法定义的表达式.匿名函数本身及其内部没有值或者类型,但是可以转换为兼容的委托或者表达式树类型(了解详情).匿名函数转换的计算取 ...

  9. 无法将具有语句体的lambda表达式转换为表达式树

    很早就碰到了这个问题,当时也没有深入的研究,趁着空闲,遂把这个问题研究清楚. (一)普通案例 下面从一个普通的案例入手,下面准备两个List集合,都是放在内存里面的(需要模拟到远端执行的时候,我们是通 ...

  10. 【BZOJ4556】字符串(后缀数组,主席树)

    [BZOJ4556]字符串(后缀数组,主席树) 题面 BZOJ 题解 注意看题: 要求的是\([a,b]\)的子串和[c,d]的\(lcp\)的最大值 先来一下暴力吧 求出\(SA\)之后 暴力枚举\ ...

随机推荐

  1. Python - 用python实现split函数

    # pattern支持字符或者字符串 def my_split(string, pattern): ret = [] len_pattern = len(pattern) while True: in ...

  2. AOP底层实现原理

    有两种方法实现: 当实现接口时,采用动态代理 另一种采用cglib cglib和动态代理并没有谁好谁坏,就像做菜一样,一种菜可以有多种味道,使用不同的方法就有不同的模式

  3. Android Studio真机无线调试

    条件 手机要和电脑处于同一局域网内(即都连同一个WiFi 或者电脑的网线另外一段连接到手机连接WiFi的路由上) 步骤 .首先将手机连接 WiFi 网络 .将手机用数据线与电脑连接,并且在电脑端 打开 ...

  4. tensorflow按需分配GPU问题

    使用tensorflow,如果不加设置,即使是很小的模型也会占用整块GPU,造成资源浪费. 所以我们需要设置,使程序按需使用GPU. 具体设置方法: gpu_options = tf.GPUOptio ...

  5. MyBatis 传一个类型为String的参数时常见问题及解决方法

    MyBatis要求如果参数为String的话,不管接口方法的形参是什么,在Mapper.xml中引用时需要改变为_parameter才能识别 : <select id="selectB ...

  6. VMware安装EVE

    众所周知,EVE是一个非常强大的仿真环境,能给我们学习带来很大的帮助,这里主要简单记录一下安装在VMware下安装EVE的过程. 1.准备: 我安装的VMware是WORKSTATION 12 PRO ...

  7. AspectRatio图片的宽高比、Card 卡片组件

    一.AspectRatio 组件 AspectRatio 的作用是根据设置调整子元素 child 的宽高比. AspectRatio 首先会在布局限制条件允许的范围内尽可能的扩展,widget 的高度 ...

  8. Java面向对象编程 -5.2

    静态代码块 静态代码块主要指的是使用static关键字定义的代码块 静态块的定义需要考虑到两种情况: 主类中定义静态块 非主类中定义静态块 静态块执行主要是给static属性进行初始化的 此时可以发现 ...

  9. webpack中使用babel

    step one: https://babeljs.io/setup Choose your tool (try CLI) select webpack Step two: npm install - ...

  10. reduxDevTool 配置

    import { createStore, compose, applyMiddleware } from 'redux' import reducer from './reducer' import ...