Parse Tree解析树计算数学表达式
依托二叉树的结构使用解析树进行数学表达式的计算,解决括号优先级计算的问题: c*(a+b)
一、Parse Tree 流程
直觉上:左括号意味着新建一棵树,右括号则是树的结束标志
具体的解析数构建流程: 初始状态 仅有root的树
识别到 ‘(’ 添加一个左节点,并移动至该新子节点
识别到 ‘[+,-,*,/]’ 将该节点的value设定为对应运算符,并添加一个右节点同时移动到该新子节点
识别到 digit 设定该节点value=digit 同时移动至父节点
识别到 ‘)’ 移动至当前节点的父节点
二、python实现
需从本地本地文件import Stack和Binary Tree
其实也很简单,Stack用list实现,Binary Tree 在数据结构Blog中有Code
from binary_tree import Binarytree
from stack.stack import Stack
# 建立Parse Tree
def buildParaseTree(fpexp:str):
fplist:list = fpexp.split()
pStack = Stack()
eTree = Binarytree(rootObj='')
pStack.push(item=eTree)
currentTree = eTree
for i in fplist:
if i == '(':
currentTree.insertLeft(newNode='')
pStack.push(item=currentTree)
currentTree = currentTree.getLeftChild()
elif i not in '+-*/)':
currentTree.setRootVal(obj=eval(i))
currentTree = pStack.pop()
elif i in '+-*/':
currentTree.setRootVal(obj=i)
currentTree.insertRight(newNode='')
pStack.push(item=currentTree)
currentTree = currentTree.getRightChild()
elif i == ')':
currentTree = pStack.pop()
else :
raise ValueError("unknown operator: " + i)
return eTree
# 对 Binary 解析树进行计算
import operator
def evaluate(parseTree:Binarytree):
# 利用后序遍历
opers = {'+': operator.add,
'-': operator.sub,
'*': operator.mul,
'/': operator.truediv}
leftC = parseTree.getLeftChild()
rightC = parseTree.getRightChild()
if leftC != None and rightC != None:
fn = opers[parseTree.getRootVal()]
return fn(evaluate(leftC),evaluate(rightC))
else:
return parseTree.getRootVal()
def printExp(tree:Binarytree):
s = ""
if tree != None:
s = '(' + printExp(tree=tree.getLeftChild())
s += str(tree.getRootVal())
s += printExp(tree=tree.getRightChild()) +')'
return s
T = buildParaseTree(fpexp="( 3 + ( 4 * 5 ) )")
# 因.split() 设定为了按照空格进行拆分字符到list,所以输入要进行空格位置保留
print(printExp(tree=T))
print(evaluate(parseTree=T))