树的应用:解析树(语法树)

将树用于表示语言中句子, 可以分析句子的各种语法成分, 对句子的各种成分进行处理

语法分析树主谓宾,定状补

程序设计语言的编译

词法、语法检查从语法树生成目标代码

自然语言处理

机器翻译、语义理解

树的应用: 表达式解析

我们还可以将表达式表示为树结构

叶节点保存操作数,内部节点保存操作符

全括号表达式((7+3)*(5-2))

由于括号的存在,需要计算*的话,就必须先计算7+3和5-2,表达式层次决定计算的优先级越底层的表达式,优先级越高

树中每个子树都表示一个子表达式

将子树替换为子表达式值的节点,即可实现求值

表达式解析树

下面, 我们用树结构来做如下尝试

从全括号表达式构建表达式解析树,利用表达式解析树对表达式求值,从表达式解析树恢复原表达式的字符串形式

首先, 全括号表达式要分解为单词Token列表

其单词分为括号“() ”、操作符“±*/”和操作数“0~9”这几类,左括号就是表达式的开始,而右括号是表达式的结束

建立表达式解析树:实例

全括号表达式: (3+(4*5))

创建表达式解析树过程

  • 创建空树,当前节点为根节点
  • 读入’(’, 创建了左子节点,当前节点下降
  • 读入’3’,当前节点设置为3, 上升到父节点
  • 读入’+’,当前节点设置为+, 创建右子节点,当前节点下降

  • 读入’(’, 创建左子节点,当前节点下降
  • 读入’4’,当前节点设置为4, 上升到父节点
  • 读入’’,当前节点设置为, 创建右子节点,当前节点下降
  • 读入’5’,当前节点设置为5, 上升到父节点
  • 读入’)’, 上升到父节点
  • 读入’)’,再上升到父节点

建立表达式解析树:规则

从左到右扫描全括号表达式的每个单词,依据规则建立解析树

如果当前单词是"(":为当前节点添加一个新节点作为其左子节点, 当前节点下降为这个新节点。如果当前单词是操符"+,-,/,*":将当前节点的值设为此符号,为当前节点添加一个新节点作为其右子节点, 当前节点下降为这个新节点,如果当前单词是操作数:将当前节点的值设为此数, 当前节点上升到父节点,如果当前单词是")":则当前节点上升到父节点

建立表达式解析树:实例

全括号表达式: (3+(4*5))

建立表达式解析树:思路

从图示过程中我们看到, 创建树过程中关键的是对当前节点的跟踪

  • 创建左右子树可调用insertLeft/Right
  • 当前节点设置值,可以调用setRootVal
  • 下降到左右子树可调用getLeft/RightChild
  • 但是, 上升到父节点,这个没有方法支持!

我们可以用一个栈来记录跟踪父节点

  • 当前节点下降时,将下降前的节点push入栈
  • 当前节点需要上升到父节点时,上升到pop出栈的节点即可!

建立表达式解析树:代码

class BinaryTree:def __init__(self, rootObj):self.key = rootObjself.leftChild = Noneself.rightChild = Nonedef insertLeft(self, newNode):if self.leftChild == None:self.leftChild = BinaryTree(newNode)else:t = BinaryTree(newNode)t.leftChild = self.leftChildself.leftChild = tdef insertRight(self, newNode):if self.rightChild == None:self.rightChild = BinaryTree(newNode)else:t = BinaryTree(newNode)t.rightChild = self.rightChildself.rightChild = tdef getRightChild(self):return self.rightChilddef getLeftChild(self):return self.leftChilddef setRootVal(self, obj):self.key = objdef getRootVal(self):return self.keyclass Stack:def __init__(self):self.items = []def isEmpty(self):return self.items == []def push(self, item):self.items.append(item)def pop(self):return self.items.pop()def peek(self):return self.items[-1]def size(self):return len(self.items)def buildParseTree(fpexp):fplist = fpexp.split()pStack = Stack()eTree = BinaryTree('')# 入栈下降pStack.push(eTree)currentTree = eTreefor i in fplist:# 表达式开始if i == '(':currentTree.insertLeft('')# 入栈下降pStack.push(currentTree)currentTree = currentTree.getLeftChild()# 操作数elif i not in ['+', '-', '*', '/', ')']:currentTree.setRootVal(int(i))# 出栈上升parent = pStack.pop()currentTree = parent# 操作符elif i in ['+', '-', '*', '/']:currentTree.setRootVal(i)currentTree.insertRight('')pStack.push(currentTree)currentTree = currentTree.getRightChild()# 表达式结束elif i == ')':# 出栈上升currentTree = pStack.pop()else:raise ValueErrorreturn eTree

创建了表达式解析树, 可用来进行求值

由于二叉树BinaryTree是一个递归数据结构, 自然可以用递归算法来处理

求值递归函数evaluate

由前述对子表达式的描述,可从树的底层子树开始,逐步向上层求值,最终得到整个表达式的值

求值函数evaluate的递归三要素:

  • 基本结束条件:叶节点是最简单的子树,没有左右子节点,其根节点的数据项即为子表达式树的值
  • 缩小规模:将表达式树分为左子树、右子树,即为缩小规模
  • 调用自身:分别调用evaluate计算左子树和右子树的值,然后将左右子树的值依根节点的操作符进行计算,从而得到表达式的值

一个增加程序可读性的技巧:函数引用

利用表达式解析树求值:代码

import operator
def evaluate(parseTree):opers = {'+': operator.add, '-': operator.sub, '*': operator.mul, '/': operator.truediv}# 缩小规模leftC = parseTree.getLeftChild()rightC = parseTree.getRightChild()if leftC and rightC:fn = opers[parseTree.getRootVal()]# 递归调用return fn(evaluate(leftC), evaluate(rightC))else:# 基本结束条件return parseTree.getRootVal()

数据结构与算法(Python版)四十八:树的应用(表达式解析)相关推荐

  1. 数据结构与算法(Python版)二十二:递归可视化(谢尔宾斯基三角形)

    谢尔宾斯基Sierpinski三角形 分形构造, 平面称谢尔宾斯基三角形, 立体称谢尔宾斯基金字塔 谢尔宾斯基三角形:作图思路 根据自相似特性, 谢尔宾斯基三角形是由3个尺寸减半的谢尔宾斯基三角形按照 ...

  2. mooc数据结构与算法python版第十周作业_中国大学mooc慕课_数据结构与算法Python版_章节答案...

    新入对于接诊人的院病与查房,中国章节在多必须经治间内进行医师长时. 大学答案高的主要文库日常利用率较有(. 须注下问题:慕课意以,者以知识作为的投资产权出资.在配置上电装,该装装在置(线应部位)的接地 ...

  3. mooc数据结构与算法python版期末考试_数据结构与算法Python版-中国大学mooc-试题题目及答案...

    数据结构与算法Python版-中国大学mooc-试题题目及答案 更多相关问题 婴儿出生一两天后就有笑的反应,这种笑的反应属于(). [判断题]填制原始凭证,汉字大写金额数字一律用正楷或草书书写,汉字大 ...

  4. python数据结构算法 北京大学_北京大学公开课《数据结构与算法Python版》

    之前我分享过一个数据结构与算法的课程,很多小伙伴私信我问有没有Python版. 看了一些公开课后,今天特向大家推荐北京大学的这门课程:<数据结构与算法Python版>. 课程概述 很多同学 ...

  5. 数据结构与算法 python版 之 递归三定律

    #数据结构与算法 python版 之 谢尔宾斯基三角形 , 树叉 1.为了向阿西莫夫的"机器人三定律"直径,递归算法也总结出"三定律" 1递归算法必须有一个基本 ...

  6. 数据结构python版 答案,中国大学 MOOC_数据结构与算法Python版_章节测验答案

    中国大学 MOOC_数据结构与算法Python版_章节测验答案 更多相关问题 认识的本质是()A.肯定世界是可知的B.主体对客体的能动反映C.主体对客体的直观反映D.实践是 水灰比是影响混凝土()的主 ...

  7. 数据结构与算法python版 MOOC 第九周

    九.树及算法-上 本系列博客基于" (北京大学)数据结构与算法python版"慕课,课程在中国大学慕课和bilibili上均可找到. 1. 内容 树结构的相关术语 树的表示方法:嵌 ...

  8. mooc数据结构与算法python版期末测验_中国大学数据结构与算法Python版答案_MOOC慕课章节期末答案...

    中国大学数据结构与算法Python版答案_MOOC慕课章节期末答案 更多相关问题 java.lang 包的 Character 类的 isJavaIdentifierStart 方法的功能是用来判断某 ...

  9. mooc数据结构与算法python版第十一周作业_中国大学 MOOC_数据结构与算法Python版_2020最新答案学习指南...

    中国大学 MOOC_数据结构与算法Python版_2020最新答案学习指南 更多相关问题 [判断题]实际集成运放的上限截止频率为无穷大 [多选题]现代城市的发展凸现出与以往不同的动力机制包括 教师在引 ...

最新文章

  1. python urllib.request 爬虫 数据处理-Python爬虫学习之(二)| urllib进阶篇
  2. 黄聪:C#代码生成工具:文本模板初体验 Hello,World!
  3. DBA查询命令积累——不断更新
  4. 【Redis】1.Redis入门简介以及基本操作命令
  5. (转)java动态代理与aop
  6. sql/c#十六进制与十进制的转换
  7. apipost 如何分享多个接口
  8. linux设置ipsan_linux 配置SAN存储-IPSAN
  9. 虚拟机Ubuntut tftp服务不启动,service tftpd-hpa restart 失败的处理
  10. win10总显示打印机未连接服务器,win10系统打印机共享提示连接失败的解决方法...
  11. The working copy needs to be upgraded
  12. 计算机酷睿处理器排行,2018电脑英特尔处理器排名(cpu性能天梯图)
  13. 一招学会绘制UI图标超椭圆
  14. 亲手打造自己的 Linux 桌面环境
  15. matlab状态空间模型构建函数ss
  16. 鲲鹏生态跑出加速度 中原数字经济再续新动能
  17. 2018十大最热门编程语言排行榜出炉,Java竟不是第一!
  18. 关于ffmpeg如何下载、安装和使用
  19. 如何利用计算机班级成绩分析,北京自考计算机应用基础课成绩分析报告
  20. 骑行318、 2016.7.30

热门文章

  1. c语言横纵坐标乘法,C语言 · 猜算式 · 乘法竖式
  2. qt开发环境的建立与qte4.6.3、tslib1.4的移植
  3. Kali Linux渗透
  4. 基于ODX 的诊断应用软件
  5. 对测绘软件南方CASS的使用感想
  6. 倍福常见端子模块汇总
  7. 开源ERP| Odoo系统如何实现企微扫码登录
  8. LeetCode初级算法 2:买卖股票的最佳时机 II
  9. 京东商城的商品分类代码
  10. 跳槽、找工作在几月份比较好?