有效地在字符串中查找任何一个子字符串

时间:2011-11-01 04:30:26

标签: string algorithm substring

假设我们有3个字符串:"ab", "cd" and "ef" 让我们假设我们要搜索的子字符串是上述字符串的排列,即any of {"abcdef","abefcd","efabcd","efcdab","cdefab","cdabcf"}
现在让我们假设我们有一个长字符串,我们希望从中找到上面集合中的任何子字符串(稍微简化一下情况并假设主字符串中只有一个子字符串只出现一次) )。
如。

Main string: abcdghefcdabgh
Substring:         efcdab

在这种情况下进行搜索的最有效方法是什么?蛮力并搜索每个可能的子串是非常低效的。
用于多模式搜索的Rabin-Karp是我想到的一种方法。但是我不确定在这种情况下什么是非常有效的哈希函数。

2 个答案:

答案 0 :(得分:1)

搜索任何“ab”,在+1或-1处找到“cd”或“ef”,继续直到找到整个排列。

示例:

使用"ab", "cd", "ef"
"asjkdnjdnaboidnabefcdasdnmk"

"ab"的第一个实例位于9,因此:

lowerFound = 9
upperfound = 11 \\ found index + length of found string

从那里你知道排列中的任何其他匹配必须在lowerfound之前或在upperfound之上,因此在两侧看,例如: dn ab oi不包含任何匹配项,因此会丢弃并在"ab"找到下一个15

lowerFound = 15
upperfound = 17
search for "cd" or "ef" at 15-length or 17
found "ab"+"ef"

lowerFound = 15
upperfound = 19
search for "cd" at 15-length or 19
found "abef"+"cd"

return

我已经制定了一个程序来实现这一目标,但它是相当大的,直线的,所以我把它right here,随意批评这种方法。
为了减少最坏情况"ababababababababcdef",您可能希望保留已在内存中搜索索引。

答案 1 :(得分:0)

我不确定是否可以找到模式字符串的所有排列,但是如果可以在合理的时间内找到这些排列,那么您可以使用此算法同时检查所有模式。 / p>

http://en.wikipedia.org/wiki/Aho%E2%80%93Corasick_string_matching_algorithm

另一个需要一些额外空间的更快的方法是在Text上构造一个后缀树。然后匹配每个模式。 使树为O(n),其中n是文本大小。 匹配每个模式是O(p),其中p是每个模式的长度。

总时间= O(p1 + p2 + p3 ... + n)

相关问题