假设我们有3个字符串:"ab", "cd" and "ef"
让我们假设我们要搜索的子字符串是上述字符串的排列,即any of {"abcdef","abefcd","efabcd","efcdab","cdefab","cdabcf"}
现在让我们假设我们有一个长字符串,我们希望从中找到上面集合中的任何子字符串(稍微简化一下情况并假设主字符串中只有一个子字符串只出现一次) )。
如。
Main string: abcdghefcdabgh
Substring: efcdab
在这种情况下进行搜索的最有效方法是什么?蛮力并搜索每个可能的子串是非常低效的。
用于多模式搜索的Rabin-Karp是我想到的一种方法。但是我不确定在这种情况下什么是非常有效的哈希函数。
答案 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)