我有数字列表,我需要创建树并打印所有排列,例如对于[1, 2, 3]
,它应该打印
123
132
213
231
312
321
目前我的代码只打印第一个元素一次:
123
32
213
31
312
21
我该如何解决?
class Node(object):
def __init__(self):
self.children = None
self.data = None
self.depth = None
class PermutationTree(object):
def __init__(self, numbers):
numbers = list(set(numbers))
numbers.sort()
self.depth = len(numbers)
self.tree = self.generate_root(numbers)
self.create_tree(numbers, self.tree.children, 1)
def generate_root(self, numbers):
root = Node()
root.children = []
root.depth = 0
for i in numbers:
tree = Node()
tree.data = i
tree.depth = 1
root.children.append(tree)
return root
def create_tree(self, numbers, children, depth):
depth += 1
if depth == self.depth + 1:
return
for child in children:
reduced_numbers = list(numbers)
reduced_numbers.remove(child.data)
child.children = []
for j in reduced_numbers:
tree = Node()
tree.data = j
tree.depth = depth
child.children.append(tree)
self.create_tree(reduced_numbers, child.children, depth)
def print_tree(self):
self.print(self.tree)
def print(self, node):
for i in node.children:
print(i.data, end="")
if not i.depth == self.depth:
self.print(i)
print("")
test = [1, 2, 3]
permutation_tree = PermutationTree(test)
permutation_tree.print_tree()
答案 0 :(得分:1)
这是一个很好的例子,说明为什么side effects应该在尽可能少的地方完成。
你的方法是这样的:“我会在每次需要时打印一个数字。”这种方法可以让你对副作用进行有限的控制。您的代码在不同的递归深度中打印很多次,并且很难跟踪发生的情况。
解决这个问题的另一种方法是在一个地方创造副作用。 “我将首先生成所有排列,然后打印它们。”这样的代码更容易调试,可以让您更好地控制代码中发生的事情。
如果您编写如下代码:
def print_tree(self): # this function takes care about printing
for path in self.generate_path(self.tree):
print(path)
def generate_perm(self, node): #this function takes care about generating permutations
if not node.children:
return [str(node.data)]
app_str = str(node.data) if node.data else ""
res= []
for child in node.children:
for semi_path in self.generate_perm(child):
res.append (app_str + semi_path)
return res
P.S。 使用yields可以重写generate_perm以提高效率。