如何使用循环引用来散列和检查对象的相等性

时间:2010-12-27 17:42:50

标签: hash graph equals circular-reference cyclic

我有循环图形式结构,由 Node 对象表示。 节点是标量值(叶子)或n> = 1 节点(内部节点)的列表。

由于可能的循环引用,我不能简单地使用递归的HashCode()函数,它结合了所有子节点的HashCode():它最终会进行无限递归。

虽然HashCode()部分似乎至少可以通过标记和忽略已经访问过的节点来实现,但我在为Equals()设计一个有效且高效的算法时遇到了一些麻烦。

令我惊讶的是,我没有找到任何有用的信息,但我确信很多聪明的人都想过解决这些问题的好方法......对吗?

示例(python):

A = [ 1, 2, None ]; A[2] = A  
B = [ 1, 2, None ]; B[2] = B

A等于B,因为它代表完全相同的图形。

顺便说一句。这个问题并不针对任何特定的语言,但是在Java中为所描述的 Node 对象实现hashCode()和equals()将是一个很好的实际例子。

3 个答案:

答案 0 :(得分:0)

如果你把它想象成图形,叶子节点是一个只有一个连接的节点,一个复杂的节点是一个至少为2的节点。所以你得到它,实现一个简单的BFS算法,应用哈希函数到它传递的每个节点,然后删除结果。通过这种方式,您可以确保自己不会陷入任何一个节点或多次通过任何节点。

实施可能非常紧张。阅读它here

答案 1 :(得分:0)

你需要走图表。

这是一个问题:这些图表是否相等?

A = [1,2,None]; A[2] = A
B = [1,2,[1,2,None]]; B[2][2] = B

如果是这样,您需要一组(节点,节点)元组。使用此set来捕获循环,并在捕获循环时返回“true”。

如果没有,您可以更高效,并使用从节点到节点的映射。然后,在走图表时,建立一组对应关系。 (在上面的例子中,A对应于B,A [2]对应于B [2],& c。)然后,当您访问节点对时,确保确切的对在地图中;如果不是图表不匹配。

答案 2 :(得分:0)

我也想知道一个好的答案。到目前为止,我使用了基于访问集的解决方案。

在计算哈希时,我遍历图结构并保留一组访问节点。我没有两次进入同一个节点。当我点击已经访问过的节点时,哈希返回一个没有递归的数字。

这项工作甚至用于平等比较。我比较节点数据并递归调用子节点。当我点击已经访问过的节点时,比较返回true而不递归。