我正在尝试找到一个算法,该算法会在较大的循环字符串中返回最短循环子字符串的长度。
循环字符串将被定义为两个或更多个同一串字符串的串联,例如, “abababab”,或“aaaa”......
现在在给定的例如字符串T =“abbcabbcabbcabbc”中,存在模式“abbc”的循环,但最短的循环子字符串将是“bb”。
答案 0 :(得分:1)
如果您只是寻找出现多次的子字符串:
从字符串中构建Suffix tree。
在创建后缀树时,您可以计算每个子字符串的重新出现次数,并将其保存在节点上出现的次数上。
然后在树上执行BFS search(这将为您提供从较短到较长字符串的分层搜索),并找到第一个超过1的子字符串,该字符串多次出现。
总复杂度: O(n)其中n是字符串的长度
编辑:
从根到叶子的路径 与...有一对一的关系 S的后缀
您可以实现每个节点包含一个字母的树,这样可以提供更好的粒度,并允许您按长度查看所有子字符串。
这是一个香蕉后缀树,每个节点都包含一个字母,你可以看到你有所有的子串。
如果您查看后缀树的applications部分,您会看到它完全用于此类任务 - 查找有关子字符串的内容。
查看根目录中的图像,可以看到所有子字符串从根目录开始(BFS列表):
b
a
n
ba
an
na
ban
ana
nan
bana
anan
nana
banan
anana
banana
答案 1 :(得分:0)
让我在您的示例中将“abbc”称为生成器 - 即您重复的字符串以获取更大的字符串。
第一个观察是,应该通过重复一些子串两次来制作较小的字符串。
很明显,最小的字符串应该小于重复两次的生成器(2 *生成器),因为2 *生成器是循环的。
现在请注意,在搜索较小的循环字符串时,您只需要考虑通过将生成器取3次获得的字符串。实际上,如果最小的不在那里,但它在4 *发电机中,那么它必须跨越至少两个发电机,但那么它不会是最小的。
所以现在让我们假设更大的字符串是3 * generator(或2 * generator)。 另外很明显,如果发电机只有不同的数字,那么答案是2 *发电机。如果没有那么你只需要在较大的字符串中找到所有相同的字符对,比如在位置i和j处,并检查以i *开头的字符串,即2 *(j-i)long是否是循环的。如果你按照增加j-i的顺序尝试它们,那么你可以在第一次成功后停止。