我正在尝试解决在对象树中找到最大重复子树的问题。
通过对象树,我的意思是一棵树,其中每个叶子和节点都有一个名称。每个叶子都有一个类型和一个与该叶子相关联的该类型的值。每个节点都有一组按一定顺序的叶子/节点。
给定一个我们知道的对象树,其中有一个重复的子树。
重复是指 2 个或更多子树,它们在所有方面(名称/类型/子元素的顺序)都相似,但叶子的值。子树之间不能共享节点/叶子。
问题是识别这些最大高度的子树。
我知道详尽的搜索可以解决问题。我宁愿寻找更有效的方法。
我正在尝试解决在对象树中找到最大重复子树的问题。
通过对象树,我的意思是一棵树,其中每个叶子和节点都有一个名称。每个叶子都有一个类型和一个与该叶子相关联的该类型的值。每个节点都有一组按一定顺序的叶子/节点。
给定一个我们知道的对象树,其中有一个重复的子树。
重复是指 2 个或更多子树,它们在所有方面(名称/类型/子元素的顺序)都相似,但叶子的值。子树之间不能共享节点/叶子。
问题是识别这些最大高度的子树。
我知道详尽的搜索可以解决问题。我宁愿寻找更有效的方法。
您可以实现 dfs 遍历,为每个节点生成一个哈希值。将这些值与节点高度一起存储在一个简单的数组中。子树候选者是重复值,只需检查候选者是否正常,因为两个不同的子树可能会产生相同的哈希值。
假设叶子和内部节点都是类型 Node 并且标准访问和遍历功能可用:
procedure dfs_update( node : Node, hashmap : Hashmap )
begin
if is_leaf(node) then
hashstring = concat("LEAF",'|',get_name_str(node),'|',get_type_str(node))
else // node is an internal node
hashstring = concat("NODE",'|',get_name_str(node))
for each child in get_children_sorted(node)
dfs_update(child,hashmap)
hashstring = concat(hashstring,'|',get_hash_string(hashmap,child))
end for
end if
// only a ref to node is added to the hashmap, we could also add
// the node's height, hashstring, whatever could be useful and inapropriate
// to keep in the Node ds
add(hashmap, hash(hashstring),node)
end
棘手的部分是在 a 之后dfs_update
,我们必须通过降低高度来获取 hasmap 中的碰撞节点列表,并逐个检查它们是否真的重复。