连接树数据 - 如何简化我的代码?
Concatenating tree data - How to simplify my code?
我解决了一个练习,在这个练习中我必须将递归算法应用于如此定义的树:
class GenericTree:
""" A tree in which each node can have any number of children.
Each node is linked to its parent and to its immediate sibling on the right
"""
def __init__(self, data):
self._data = data
self._child = None
self._sibling = None
self._parent = None
我必须将叶子的数据与 parents 的数据连接起来,依此类推,直到我们到达将具有所有叶子数据总和的根。我以这种方式解决了它并且它有效但它似乎非常曲折和机械:
def marvelous(self):
""" MODIFIES each node data replacing it with the concatenation
of its leaves data
- MUST USE a recursive solution
- assume node data is always a string
"""
if not self._child: #If there isn't any child
self._data=self._data #the value remains the same
if self._child: #If there are children
if self._child._child: #if there are niece
self._child.marvelous() #reapply the function to them
else: #if not nieces
self._data=self._child._data #initializing the name of our root node with the name of its 1st son
#if there are other sons, we'll add them to the root name
if self._child._sibling: #check
current=self._child._sibling #iterating through the sons-siblings line
while current:
current.marvelous() #we reapplying the function to them to replacing them with their concatenation (bottom-up process)
self._data+=current._data #we sum the sibling content to the node data
current=current._sibling #next for the iteration
#To add the new names to the new root node name:
self._data="" #initializing the root str value
current=self._child #having the child that through recursion have the correct str values, i can sum all them to the root node
while current:
self._data+=current._data
current=current._sibling
if self._sibling: #if there are siblings, they need to go through the function themselves
self._sibling.marvelous()
基本上我会检查传递的节点树是否有children:如果没有,它会保留相同的数据。
如果有 children,我检查是否有侄女:在这种情况下,我重新启动算法,直到我可以将一些叶子添加到 pre-terminal 节点,然后我对叶子值求和以将该总和加到它们的值上parents'数据。
然后,我用第一个 while 循环后的代码作用于根节点,因此将其名称作为所有叶子的总和。
最后一段代码用于使代码在每个步骤中都适合兄弟姐妹。
我该如何改进它?
在我看来,您的方法执行了很多冗余的递归调用。
例如,您代码中的这个循环:
while current:
current.marvelous()
self._data += current._data
current = current._sibling
没有用,因为递归调用无论如何都会由最后一个执行
您方法中的说明 (self._sibling.marvelous()
)。除了,
您更新 self._data
然后在循环之后立即重置
self._data
到 ""
.
我试图简化它并想出了这个似乎
工作。
def marvelous(self):
if self.child:
self.child.marvelous()
# at that point we know that the data for all the tree
# rooted in self have been computed. we collect these
self.data = ""
current = self.child
while current:
self.data += current.data
current = current.sibling
if self.sibling:
self.sibling.marvelous()
这里有一个更简单的解决方案:
def marvelous2(self):
if not self.child:
result = self.data
else:
result = self.child.marvelous2()
self.data = result
if self.sibling:
result += self.sibling.marvelous2()
return result
marvelous2
returns 为节点及其所有兄弟节点计算的数据。这样就避免了执行前面方案的while循环
我解决了一个练习,在这个练习中我必须将递归算法应用于如此定义的树:
class GenericTree:
""" A tree in which each node can have any number of children.
Each node is linked to its parent and to its immediate sibling on the right
"""
def __init__(self, data):
self._data = data
self._child = None
self._sibling = None
self._parent = None
我必须将叶子的数据与 parents 的数据连接起来,依此类推,直到我们到达将具有所有叶子数据总和的根。我以这种方式解决了它并且它有效但它似乎非常曲折和机械:
def marvelous(self):
""" MODIFIES each node data replacing it with the concatenation
of its leaves data
- MUST USE a recursive solution
- assume node data is always a string
"""
if not self._child: #If there isn't any child
self._data=self._data #the value remains the same
if self._child: #If there are children
if self._child._child: #if there are niece
self._child.marvelous() #reapply the function to them
else: #if not nieces
self._data=self._child._data #initializing the name of our root node with the name of its 1st son
#if there are other sons, we'll add them to the root name
if self._child._sibling: #check
current=self._child._sibling #iterating through the sons-siblings line
while current:
current.marvelous() #we reapplying the function to them to replacing them with their concatenation (bottom-up process)
self._data+=current._data #we sum the sibling content to the node data
current=current._sibling #next for the iteration
#To add the new names to the new root node name:
self._data="" #initializing the root str value
current=self._child #having the child that through recursion have the correct str values, i can sum all them to the root node
while current:
self._data+=current._data
current=current._sibling
if self._sibling: #if there are siblings, they need to go through the function themselves
self._sibling.marvelous()
基本上我会检查传递的节点树是否有children:如果没有,它会保留相同的数据。 如果有 children,我检查是否有侄女:在这种情况下,我重新启动算法,直到我可以将一些叶子添加到 pre-terminal 节点,然后我对叶子值求和以将该总和加到它们的值上parents'数据。 然后,我用第一个 while 循环后的代码作用于根节点,因此将其名称作为所有叶子的总和。 最后一段代码用于使代码在每个步骤中都适合兄弟姐妹。 我该如何改进它?
在我看来,您的方法执行了很多冗余的递归调用。
例如,您代码中的这个循环:
while current:
current.marvelous()
self._data += current._data
current = current._sibling
没有用,因为递归调用无论如何都会由最后一个执行
您方法中的说明 (self._sibling.marvelous()
)。除了,
您更新 self._data
然后在循环之后立即重置
self._data
到 ""
.
我试图简化它并想出了这个似乎 工作。
def marvelous(self):
if self.child:
self.child.marvelous()
# at that point we know that the data for all the tree
# rooted in self have been computed. we collect these
self.data = ""
current = self.child
while current:
self.data += current.data
current = current.sibling
if self.sibling:
self.sibling.marvelous()
这里有一个更简单的解决方案:
def marvelous2(self):
if not self.child:
result = self.data
else:
result = self.child.marvelous2()
self.data = result
if self.sibling:
result += self.sibling.marvelous2()
return result
marvelous2
returns 为节点及其所有兄弟节点计算的数据。这样就避免了执行前面方案的while循环