基于 Python 的数据结构与算法分析学习记录(6-6)—— 分析树
2017-05-07 18:14
459 查看
分析树可以用于表示诸如句子或数学表达式的真实世界构造。
在本节的其余部分,我们将更详细地检查分析树。 特别的,我们会看
如何从完全括号的数学表达式构建分析树。
如何评估存储在分析树中的表达式。
如何从分析树中恢复原始数学表达式。
我们知道,每当我们读一个左括号,我们开始一个新的表达式,因此我们应该创建一个新的树来对应于该表达式。 相反,每当我们读一个右括号,我们就完成了一个表达式。 我们还知道操作数将是叶节点和它们的操作符的子节点。 最后,我们知道每个操作符都将有一个左和右孩子。
使用上面的信息,我们可以定义四个规则如下:
如果当前符号是 ‘(‘,添加一个新节点作为当前节点的左子节点,并下降到左子节点。
如果当前符号在列表 [‘+’,’ - ‘,’/’,’*’] 中,请将当前节点的根值设置为由当前符号表示的运算符。 添加一个新节点作为当前节点的右子节点,并下降到右子节点。
如果当前符号是数字,请将当前节点的根值设置为该数字并返回到父节点。
如果当前符号是 ‘)’,则转到当前节点的父节点。
我们将使用表达式
在本节的其余部分,我们将更详细地检查分析树。 特别的,我们会看
如何从完全括号的数学表达式构建分析树。
如何评估存储在分析树中的表达式。
如何从分析树中恢复原始数学表达式。
我们知道,每当我们读一个左括号,我们开始一个新的表达式,因此我们应该创建一个新的树来对应于该表达式。 相反,每当我们读一个右括号,我们就完成了一个表达式。 我们还知道操作数将是叶节点和它们的操作符的子节点。 最后,我们知道每个操作符都将有一个左和右孩子。
使用上面的信息,我们可以定义四个规则如下:
如果当前符号是 ‘(‘,添加一个新节点作为当前节点的左子节点,并下降到左子节点。
如果当前符号在列表 [‘+’,’ - ‘,’/’,’*’] 中,请将当前节点的根值设置为由当前符号表示的运算符。 添加一个新节点作为当前节点的右子节点,并下降到右子节点。
如果当前符号是数字,请将当前节点的根值设置为该数字并返回到父节点。
如果当前符号是 ‘)’,则转到当前节点的父节点。
我们将使用表达式
(3+(4 * 5))。 我们将把这个表达式解析成下面的字符标记列表
['(','3','+','(','4','*','5',')',')']。 最初,我们将使用由空根节点组成的分析树开始。
# -*- coding:utf-8 -*- import operator class 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[len(self.items)-1] def size(self): return len(self.items) class BinaryTree: def __init__(self, rootObj): self.key = rootObj self.leftChild = None self.rightChild = None def insertLeft(self, newNode): if self.leftChild is None: self.leftChild = BinaryTree(newNode) else: t = BinaryTree(newNode) t.leftChild = self.leftChild self.leftChild = t def insertRight(self, newNode): if self.rightChild is None: self.rightChild = BinaryTree(newNode) else: t = BinaryTree(newNode) t.rightChild = self.rightChild self.rightChild = t def getLeftChild(self): return self.leftChild def getRightChild(self): return self.rightChild def setRootVal(self, obj): self.key = obj def getRootVal(self): return self.key def buildParseTree(fpexp): fplist = fpexp.split() pStack = Stack() eTree = BinaryTree('') # 栈底 pStack.push(eTree) currentTree = eTree for i in fplist: if i == '(': currentTree.insertLeft('') pStack.push(currentTree) currentTree = currentTree.getLeftChild() elif i == ')': currentTree = pStack.pop() elif i in ['+', '-', '*', '/']: currentTree.setRootVal(i) currentTree.insertRight('') pStack.push(currentTree) currentTree = currentTree.getRightChild() elif i not in ['+', '-', '*', '/']: currentTree.setRootVal(int(i)) parent = pStack.pop() currentTree = parent else: raise ValueError return eTree 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() pt = buildParseTree("( ( 10 + 5 ) * 3 )") print(evaluate(pt))
相关文章推荐
- Python数据结构与算法分析学习记录(1)——基于Problem Solving with Algorithms and Data Structures using Python的学习
- 基于 Python 的数据结构与算法分析学习记录(6-5)——树的节点表示
- Python数据结构与算法分析学习记录(2)——基于Problem Solving with Algorithms and Data Structures using Python的学习
- 基于 Python 的数据结构与算法分析学习记录(6-8)—— 基于二叉堆的优先队列
- 基于 Python 的数据结构与算法分析学习记录(6-10)—— 二叉堆实现
- 基于 Python 的数据结构与算法分析学习记录(6-11)—— 二叉查找树与操作
- 基于 Python 的数据结构与算法分析学习记录(6-9)—— 二叉堆操作
- 基于 Python 的数据结构与算法分析学习记录(6-7)—— 树的遍历
- 【利用python进行数据分析-学习记录】python-matplotlib中Basemap插件的安装
- 基于Problem Solving with Algorithms and Data Structures using Python的学习记录(3)——Basic Data Structures
- Dive Into Python 学习记录3-对获取某文件夹下MP3文件信息的代码构成分析
- 基于Problem Solving with Algorithms and Data Structures using Python的学习记录(6-1)——Tree
- Python: 利用Python进行数据分析 学习记录
- 基于binlog来分析mysql的行记录修改情况(python脚本分析)
- 基于Problem Solving with Algorithms and Data Structures using Python的学习记录(5)——Sorting
- Jrtplib学习分析与记录2
- 基于python wxpython的简易计算器的源码(供大家学习)
- Jrtplib学习分析与记录3
- Jrtplib学习分析与记录2
- 数据库学习:oracle的递归写法,分析函数写法,以及teradata的取一定数量记录的写法