一阶谓词表达式转二叉树 Python

一阶谓词表达式转二叉树 Python,第1张

一阶谓词表达式转二叉树 Python 一阶谓词表达式转二叉树 Python

原理类似于中缀表达式转二叉树,把运算符的优先级换掉就可以了

但是谓词表达式要注意三个运算符﹁,∃x,∀x,因为它们三都是只有一个运算数的,需要单独处理

主要思想:输入中缀一阶谓词表达式,先将中缀表达式转后缀表达式,再将后缀表达式构建二叉树,最后打印二叉树

放上代码,有兴趣的同学可以看一下,还不太完善,有什么好的改进方法欢迎交流
可以加一个字符串的切分函数,以及错误判断

#####一阶谓词表达式转二叉树######
# coding:UTF8
import sys

from binarytree import build
import random
import networkx as nx
import matplotlib.pyplot as plt
from collections import defaultdict

from notebook.notebookapp import raw_input


class TNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None


class Solution:
    # 判断是否是运算符
    def isOper(self, ch):
        '''if ch in ['+', '-', '*', '/', '^', '(', ')']:
            return True
        return False'''
        if ch in ['!', '%x', '&x', '<', '>', '->', '(', ')', '%y', '&y']:
            return True
        return False

    # 获取运算符所对应的优先级别
    def getOperOrder(self, ch):
        if ch == '(':
            return 1
        if ch in ['!', '%x', '&x', '%y', '&y']:
            return 2
        if ch in ['<', '>']:
            return 3
        if ch == ['->','<->']:
            return 4
        if ch == '^':
            return 5
        return 0

    # 创建二叉树
    def createTree(self, data):
        if not data:
            return
        ch = data.pop(0)
        if ch == '#':
            return None
        else:
            root = TNode(ch)
            root.left = self.createTree(data)
            root.right = self.createTree(data)
            return root

    # 后缀表达式生成二叉树
    def PostExpTree(self, data):
        if not data:
            return
        re = []
        while data:
            tmp = data.pop(0)
            if not self.isOper(tmp):
                re.append(TNode(tmp))
            elif tmp in ['!', '%x', '&x', '%y', '&y']:   ##单独处理只有一个运算数的运算符
                p = TNode(tmp)
                p.right = re.pop()
                re.append(p)
            else:
                p = TNode(tmp)
                p.right = re.pop()
                p.left = re.pop()
                re.append(p)
        return re.pop()
        
# 中缀表达式生成二叉树
    def InExpTree(self, data):
        re = []
        op = []
        while data:
            tmp = data.pop(0)
            if not self.isOper(tmp):  #判断是否是运算符
                re.append(tmp)
            else:
                if tmp == '(':
                    op.append('(')
                elif tmp == ')':
                    while op[-1] != '(':
                        re.append(op.pop())
                    op.pop()
                elif tmp in ['!', '%x', '&x', '<', '>', '->','<->', '%y', '&y']:
                    while op and op[-1] != '(' and self.getOperOrder(op[-1]) > self.getOperOrder(tmp):
                        re.append(op.pop())
                    op.append(tmp)
        if op:
            re = re + op[::-1]
        #print(re)
        return self.PostExpTree(re)  #后缀表达式生成二叉树

def draw(node):  # 以某个节点为根画图
    saw = defaultdict(int)

    def create_graph(G, node, p_name, pos={}, x=0, y=0, layer=1):
        if not node:
            return
        name = str(node.val )
        saw[name] += 1
        if name in saw.keys():
            name += ' ' * saw[name]

        if layer != 1:
           G.add_edge(p_name, name)
        pos[name] = (x, y)

        l_x, l_y = x - 2 / 3 ** layer, y - 1
        l_layer = layer + 1
        create_graph(G, node.left, name, x=l_x, y=l_y, pos=pos, layer=l_layer)

        r_x, r_y = x + 2 / 3 ** layer, y - 1
        r_layer = layer + 1
        create_graph(G, node.right, name, x=r_x, y=r_y, pos=pos, layer=r_layer)
        return (G, pos)

    graph = nx.DiGraph()
    graph, pos = create_graph(graph, node, "     ")
    pos["     "] = (0, 0)
    fig, ax = plt.subplots(figsize=(8, 10))  # 比例可以根据树的深度适当调节
    nx.draw_networkx(graph, pos, ax=ax, node_size=1000)
    plt.show()


#data = ['&x', '(', 'd', '->', 'a', ')']
data = ['&x', '(', 'd', '->', '!', 'a', ')']
#data = ['(', '(', 'd', '->', 'a', ')', '->', 'c', ')']
#data = sys.stdin.readline().strip()
data = raw_input("input:")
data = data.strip().split()   #将输入按空格分隔,放入list中 
#print(type(data))
#print(data)
s = Solution()
res = []
#s.InorderTree(t1)
tree = s.InExpTree(data)  # 中缀表达式生成二叉树
s.InorderTree(tree)
res = map(str, res)
print(''.join(res))
draw(tree)

输出结果:

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5482244.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-12
下一篇 2022-12-12

发表评论

登录后才能评论

评论列表(0条)

保存