15_資料結構與演算法_分析樹_Python實現
阿新 • • 發佈:2018-11-19
#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()