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

4 篇文章 0 订阅

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

#####一阶谓词表达式转二叉树######
# coding:UTF8
import networkx as nx
import matplotlib.pyplot as plt
from collections import defaultdict

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 InorderTree(self, pNode):
if not pNode:
return
if pNode.left:
# 如果左子树是符号，且优先级低于父节点的优先级则需要加括号
if self.isOper(pNode.left.val) and self.getOperOrder(pNode.left.val) < self.getOperOrder(pNode.val):
res.append('(')
self.InorderTree(pNode.left)
res.append(')')
else:
self.InorderTree(pNode.left)
res.append(pNode.val)
if pNode.right:
# 如果有子树是符号且优先级低于父节点的优先级，则需要加括号
if self.isOper(pNode.right.val) and self.getOperOrder(pNode.right.val) <= self.getOperOrder(pNode.val):
res.append('(')
self.InorderTree(pNode.right)
res.append(')')
else:
self.InorderTree(pNode.right)

# 创建二叉树
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:
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 = 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)


————————————更新啦———————————————

def SplitString(data):
yub = list()
#这个只能一位一位的处理
i = 0
while(i < (len(data))):
if  ord(data[i]) >= 65 and ord(data[i]) <= 90:
#记录跟着谓词符号后面的部分有多长
#要找第（函数个数+1）个右括号
j = i+1
length = 0#记录谓词符号后面部分的长度
count = 0#记录谓词符号内部函数的个数
num = 0#记录这是当前第几个右括号
while (data[j-1]==')' and num==count+1)!=True:
if ord(data[j])>=97 and ord(data[j])<=122 and data[j+1]=='(':
count = count+1
elif data[j]==')':
num = num+1
j = j+1
length = length+1
print('length  ',length)

temp = ''
for k in range(length+1):
temp = temp + data[i+k]
print('temp', temp)
yub.append(temp)
i = i + length +1
elif  (data[i] == '&') or (data[i] == '%') or (data[i] == '-'):
yub.append(data[i] + data[i+1])
i = i+2
else: #(data[i] == '(') or (data[i] == ')') or (data[i] == '&') or (data[i] == '|') or (data[i] == '!'):
yub.append(data[i])
i = i+1
return yub

• 3
点赞
• 11
收藏
觉得还不错? 一键收藏
• 17
评论
06-04 1万+
09-07 280
12-09 4617
03-22 129
01-02 4633
09-19
12-15
08-19 1万+
10-09 2564
03-23 2691

### “相关推荐”对你有帮助么？

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、付费专栏及课程。