我有循环图形式结构,由 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()将是一个很好的实际例子。
答案 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而不递归。