#Created By: Chen Da
#这里针对简单的数学表达式使用分析树
"""
(3+(4*5))
定义四个规则:
1、如果当前符号是'(',添加一个新节点作为当前节点的左子节点,并下降到左子节点;
2、如果当前符号在列表['+','-','/','*']中,将当前节点的根植设置为由当前符号表示的运算符,添加一个新节点作为当前节点的右子节点,
并下降到右子节点;
3、如果当前符号是数字,请将当前节点的根植设置为该数字并返回父节点;
4、如果当前令牌是')',则转到当前节点的父节点。
"""
#先创建一个stack类
class Stack(object):
def __init__(self):
self.items = []
def is_empty(self):
return len(self.items) == 0
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(object):
def __init__(self,root_obj):
self.key = root_obj
self.left_child = None
self.right_child = None
def insert_left(self,new_node):
if self.left_child is None:
self.left_child = BinaryTree(new_node)
else:
tree_ = BinaryTree(new_node)
tree_.left_child = self.left_child
self.left_child = tree_
def insert_right(self,new_node):
if self.right_child is None:
self.right_child = BinaryTree(new_node)
else:
tree_ = BinaryTree(new_node)
tree_.right_child = self.right_child
self.right_child = tree_
def get_left_child(self):
return self.left_child
def get_right_child(self):
return self.right_child
def get_root_val(self):
return self.root_obj
def set_root_val(self,obj):
self.key = obj
#创建一个分析树
def build_parse_tree(fpexp):
fp_list = fpexp.split()
p_stack = Stack()
e_tree = BinaryTree('') #创建一个空树
p_stack.push(e_tree)
current_tree = e_tree
for i in fp_list:
if i == '(':
current_tree.insert_left(i) #创建一个新节点作为根的左子节点
p_stack.push(current_tree)
current_tree = current_tree.get_left_child() #使当前节点到该新子节点
elif i not in ['+','-','/','*']:
current_tree.set_root_val(int(i)) #将当前根值设置为该整数
parent = p_stack.pop()
current_tree = parent #使当前节点返回到父节点
elif i in ['+','-','/','*']:
current_tree.set_root_val(i) #将当前根节点的根值设置为运算符号
current_tree.insert_right('') #添加一个新节点作为右子节点
p_stack.push(current_tree)
current_tree = current_tree.get_right_child() #当前节点指向新的右子节点
elif i == ')':
current_tree = p_stack.pop() #当前节点返回父节点
else:
raise ValueError
return e_tree
#写一个评估分析树的函数,简单的返回对应叶节点的值
def test_parse_tree(parse_tree):
import operator
opers = {
'+':operator.add,'-':operator.sub,
'*':operator.mul,'/':operator.truediv
}
#获取当前节点左右子节点的引用
left_child = parse_tree.get_left_child()
right_child = parse_tree.get_right_child()
#判断如果左右子树都是None,当前节点是一个叶节点
#如果当前节点不是叶节点,将当前节点的运算符应用于递归计算左右子节点的运算中
if left_child and right_child:
fn = opers(parse_tree.get_root_val())
return fn(test_parse_tree(left_child),test_parse_tree(right_child))
else:
return parse_tree.get_root_val()
15_数据结构与算法_分析树_Python实现
猜你喜欢
转载自blog.csdn.net/PyDarren/article/details/83830124
今日推荐
周排行