子串搜索的高效数据结构?

时间:2012-03-09 15:13:21

标签: string algorithm data-structures

假设我有一组字符串S和一个查询字符串q。我想知道S的任何成员是否是q的子串。 (出于这个问题的目的,substring包含相等,例如“foo”是“foo”的子串。)例如,假设执行我想要的函数称为anySubstring

S = ["foo", "baz"]
q = "foobar"
assert anySubstring(S, q)  # "foo" is a substring of "foobar"

S = ["waldo", "baz"]
assert not anySubstring(S, q)

是否有任何易于实现的算法,len(S)中的时间复杂度为子线性?如果必须首先将S处理成一些聪明的数据结构,这是可以的,因为我将使用大量q字符串查询每个S,因此这种预处理的摊销成本可能是合理的。

编辑:为了澄清,我不在乎哪个成员的S是q的子字符串,只是至少有一个是。换句话说,我关心布尔答案。

3 个答案:

答案 0 :(得分:13)

我认为Aho-Corasick algorithm可以满足您的需求。我认为还有另一个解决方案非常简单,它是Karp-Rabin algorithm

答案 1 :(得分:2)

因此,如果S的长度小于潜在子串的长度之和,那么最好的选择是从S构建suffix tree然后在其中进行搜索。这相对于S的长度加上候选子串的总长度是线性的。当然,由于必须至少通过所有输入,因此不能有更复杂的算法。如果情况相反,即s的长度大于子串的总长度,那么最佳选择是aho-corasick

希望这有帮助。

答案 2 :(得分:1)

创建正则表达式.*(S1|S2|...|Sn).*并构建其最小DFA。

通过DFA运行您的查询字符串。