Algorithm 使用后缀数组查找两个输入字符串的一组重复的、不重叠的子字符串

Algorithm 使用后缀数组查找两个输入字符串的一组重复的、不重叠的子字符串,algorithm,suffix-tree,suffix-array,Algorithm,Suffix Tree,Suffix Array,输入:两个字符串A和B 输出:一组重复的、不重叠的子字符串 我必须找到所有重复的字符串,每个字符串必须在两个(!)字符串中至少出现一次。例如,让我们 A=“xyabcxeeyabczeee”和B=“yxabcxeee” 那么有效的输出将是{“abcx”、“ab”、“ee”},而不是“eee”,因为它只出现在字符串a中 我认为这个问题与“超最大重复”问题密切相关。以下是一个定义: 最大重复对: S中的一对相同的子串alpha和beta,以便扩展alpha和beta 任何一个方向都会破坏两个字符串的

输入:两个字符串A和B

输出:一组重复的、不重叠的子字符串

我必须找到所有重复的字符串,每个字符串必须在两个(!)字符串中至少出现一次。例如,让我们

A=“xyabcxeeyabczeee”和B=“yxabcxeee”

那么有效的输出将是{“abcx”、“ab”、“ee”},而不是“eee”,因为它只出现在字符串a中

我认为这个问题与“超最大重复”问题密切相关。以下是一个定义:

最大重复对: S中的一对相同的子串alpha和beta,以便扩展alpha和beta 任何一个方向都会破坏两个字符串的相等性 它表示为三元组(位置1、位置2、长度)

最大重复次数: “出现在S中最大对中的S的子串”。 示例:S中的abc=XabcyiizabCqabcyrxar。 注意:可以有许多最大重复对,但只能有有限的重复对 最大重复次数

超最大重复 “从未作为任何其他最大重复的子串出现的最大重复” 示例:S中的abcy=xabcyiiizabcqabcyrxar

查找所有超最大重复的算法在“字符串、树和序列的算法”中有描述,但仅适用于后缀树

其工作原理如下: 1.)使用DFS查找所有左侧不同的节点

对于S中的每个位置i,S(i-1)称为左字符i。 T(S)中叶子的左字符是后缀位置的左字符 以那片叶子为代表。 T(S)中的一个内部节点v称为左多样的,如果v中至少有两个叶 子树具有不同的左字符

2.)在这些节点上应用定理7.12.4:

左多样内部节点v表示超最大重复A当且仅当 v的所有子对象都是叶子,每个子对象都有一个明显的左字符

当我们检查v的叶子时,字符串A和B可能都必须连接起来 在第二步中,我们还必须施加一个额外的约束,即 字符串A和B中至少有一个不同的左字符。这可以通过比较 它们相对于A长度的位置。如果位置(左字符)>长度(A),则左字符在A中,否则在B中


你能用后缀+lcp数组帮我解决这个问题吗?

听起来你在寻找两个输入字符串的所有子字符串的集合交集。在这种情况下,还应返回单字母子字符串。让s1和s2作为字符串,s1是两个字符串中较短的一个。在考虑了一段时间之后,我认为你不会比直观的O(n^3m)或O(n^3)算法更好,其中n是s1的长度,m是s2的长度。我认为后缀树在这里帮不了你

for(int i=0 to n-1){
    for(int j=1 to n-i){
        if(contains(s2,substring(s1,i,j))) emit the substring
    }
}
运行时来自(n^2)/2次循环迭代,每次执行最坏情况下的O(nm)包含操作(可能是O(n),具体取决于实现)。但这并不是很糟糕,因为前面会有一个比1小得多的常数,因为子串的长度实际上在1到n之间。
如果不需要单字符匹配,可以将j初始化为2或更高的值

顺便说一句:不要用子字符串创建新字符串,查找/创建一个包含标记和原始字符串的函数,只需查看其中的字符,包括i,不包括j