我遇到了一个问题,需要一个包含字符串S的数据结构,并允许我:
我发现由Ukkonen算法构建的suffix trees是我正在寻找的。算法被描述为"On-line construction of suffix trees",我遇到了“在线”部分的问题:插入每个字符算法后,构造一个隐式后缀树,可以在最后一步中转换为显式。但是如果我想在该步骤之前使用隐式树进行搜索呢? “在线”表明在插入任何分析字符串的前缀后可以实现,但我找不到任何在隐式树上运行的最简单算法的例子。
我的问题是:如何在隐式后缀树中搜索字符串?
编辑:我接受了一个非常好的答案来解决我的问题,但在此期间我设法找到了一个简单的解决方案2:它足以搜索长度为S的后缀为U的U | U |使用KMP算法,最后匹配的字符数将是字符串重叠。答案 0 :(得分:2)
隐式后缀树和显式后缀树之间只有一个区别:它不包含字符串结束标记(并且不包含与这些字符串结束标记对应的任何分支)。
这意味着搜索子字符串的位置没有区别 - 在隐式后缀树或显式后缀树中。由于隐式后缀树包含较少的不必要分支,因此这可以保证子串搜索的效率更高(但仍然是线性时间)。
因此自动满足要求#1:只需从根搜索后缀树,然后选择与给定单词匹配的分支。
对于要求#2,我认为,你不能用相同的隐式后缀树来满足它。因为您需要字符串结束标记来处理后缀。
但是您可以在O(|U|)
时间内为给定的单词U
使用单独的(显式)后缀树。诀窍是在构造后缀树之前反转这个词。要查找S
的最长后缀(也是U
的前缀),请使用此单独的后缀树查找反向字符串S
的最长前缀,该字符串也是反向字符串的后缀字符串U
。只需从根目录中搜索此后缀树,选择与反向字符串S
匹配的分支,并记住带有字符串结束标记的最新节点。然后反转从根到此节点的路径上的字符串(或确定此路径的长度,并从S
的尾部复制相同长度的子字符串。)