使用python中的递归_hash__()函数从根节点数组中删除重复的树

ki1q1bka  于 2021-09-08  发布在  Java
关注(0)|答案(2)|浏览(274)

我试图从根节点数组中删除重复的树。我尝试通过创建一个自定义hash()函数并将各种根节点放入一个集合来删除重复项。下面是我的错误实现。

class Node: 
def __init__(self, entity, size, delay, left_child, right_child, padding): 
    # self.key = key 
    self.entity = entity
    self.size = size
    self.delay = delay
    self.left_child = left_child
    self.right_child = right_child
    self.padding = padding

def __hash__(self):
    if self is None:
        return hash(None)

    return hash(('delay', self.delay, 'size', self.size, 'entity', self.entity, 'padding', self.padding,  
    'left_child', hash(self.left_child),
    'right_child', hash(self.right_child)))

在运行下面的代码时,我得到了一个长度为3的数组,而不是预期的长度为2的数组,因为集合中只有两个唯一的根,因为node2的值与node1的值相同。

node0 = Node(1, 1, 1, None, None, None)
node1 = Node(1, 2, 3, node0, node0, None)
node2 = Node(1, 2, 3, node0, node0, None)
remove_duplicate_test = list(set([node0, node0, node1, node1, node2, node2]))

出乎意料的是,下面的代码确实返回了预期的长度为2的数组。我假设它将返回与上述代码片段相同的输出,因为它本质上是相同的代码,但遗憾的是。

node0 = Node(1, 1, 1, None, None, None)
node1 = Node(1, 2, 3, node0, node0, None)
node2 = node1
remove_duplicate_test = list(set([node0, node0, node1, node1, node2, node2]))

感谢您的指导。
以前的eq()函数有错误

def __eq__(self, other):
        if self is None and other is None:
            return True

        # 2. Both non-empty -> Compare them
        if self is not None and other is not None:
            return ((self.delay == other.delay and 
                    self.size == other.size and 
                    self.entity == other.entity and 
                    self.padding == other.padding) and 
                    __eq__(self.left_child, other.left_child) and
                    __eq__(self.right_child, other.right_child))

        # 3. one empty, one not -- false
        return False
sg2wtvxw

sg2wtvxw1#

只有当节点比较为相等时,集合中的“重复”节点才会被删除,除非您定义自己的节点,否则它们不会被删除 __eq__ 方法。规则是,如果一个对象的两个示例比较相等,那么它们必须具有相同的哈希值。但是,具有相同哈希值的两个对象可能不进行相等的比较。您可以通过定义自己的 __eq__ 方法。
尝试将以下方法添加到类中:

def __eq__(self, node2):
    return self.entity      == node2.entity and \
           self.size        == node2.size and \
           self.delay       == node2.delay and \
           self.left_child  == node2.left_child and \
           self.right_child == node2.right_child and \
           self.padding     == node2.padding

这将使具有相同字段的两个节点进行相等的比较。连同你的 __hash__ 方法,这将导致删除集合中的重复(等效)节点。
注意:如果要定义 __hash__ 这样地。否则,如果更改 setdict ,它将以错误的哈希值存储。

iq3niunx

iq3niunx2#

使用set find node2作为node1的副本,因为它们是不同的变量。但是,如果将哈希函数用作唯一项,则应该可以使用,因为node1的哈希应该与node2的哈希相同。然后,您需要弄清楚如何将散列与节点对齐。您可以通过迭代而不是列表理解来实现这一点:

node_set = set()
node_hash_set = set()
for node in [node0, node1, node2]:
    hash_of_node = hash(node) 
    if hash_of_node not in node_hash_set:
        node_hash_set.add(hash_of_node)
        node_set.add(node)

相关问题