String 在包含子字符串的字符串集中查找字符串的快速方法 任务

String 在包含子字符串的字符串集中查找字符串的快速方法 任务,string,algorithm,indexing,substring,String,Algorithm,Indexing,Substring,我有一个n=10000000字符串S的集合,需要找到包含子字符串p的S的字符串S的集合Sp 简单解 当我使用C#时,这是一个使用LINQ的非常简单的任务: string[] S = new string[] { "Hello", "world" }; string p = "ll"; IEnumerable<string> S_p = S.Where(s => s.Contains(p)); string[]S=新字符串[]{“你好”,“世界”}; 字符串p=“ll”; IE

我有一个n=10000000字符串S的集合,需要找到包含子字符串p的S的字符串S的集合Sp

简单解 当我使用C#时,这是一个使用LINQ的非常简单的任务:

string[] S = new string[] { "Hello", "world" };
string p = "ll";
IEnumerable<string> S_p = S.Where(s => s.Contains(p));
string[]S=新字符串[]{“你好”,“世界”};
字符串p=“ll”;
IEnumerable S_p=S,其中(S=>S.Contains(p));
问题 如果S包含许多字符串(如上面提到的10000000个字符串),那么速度会非常慢

主意 建立某种索引以更快地检索Sp

问题:
为该任务索引S的最佳方法是什么?您是否有任何C#实现?

这里有一种方法:
1.创建一个字符串
T=S[0]+sep_0+S[1]+sep_1+…+S[n-1]+sep_n-1
(其中
sep_i
是一个唯一的字符,对于任何
j
(如果字符集不够大,它实际上可以是一个整数)。
2.为
T
建立后缀树(可以在线性时间内完成)。
3.对于每个查询字符串
Q
遍历后缀树(需要
O(长度(Q))
时间)。然后,所有可能的答案都将位于某些子树的叶子上。所以你可以穿过这些树叶。如果
Q
相当长,则此子树中的叶数可能比
n
小得多

4.如果
Q
非常短,那么子树中的叶子数量可能非常大。这就是为什么可以对短查询字符串使用另一种策略:预计算
s[0]的所有短子字符串。。。S[n-1]
并为每个索引存储一组索引。然后,您可以只打印给定
Q
的这些索引。很难说“short”在这里到底是什么意思,但可以通过实验找到它。

我读了一些关于后缀树的文章,现在似乎建议使用后缀数组。有什么是我监督的,或者你同意吗?@user2033412查找查询字符串的发生范围可以在后缀数组中的O(长度(Q)*logn)中完成,除非你使用哈希来比较字符串,但一般来说,后缀数组在这里也是一个很好的选择,j或者我需要不同的吗?@user2033412对于后缀树,它们肯定应该不同,对于所有
I
使用相同分隔符的后缀数组,它们看起来很好。@user2033412您仍然需要它。例如,如果在没有分隔符的情况下将
aa
bb
连接在一起,您将得到
aabb
,并最终在那里找到
ab
,即使它不是其中任何一个的子字符串。您的集合S是常量吗?同一个S使用了多少个不同的p?是的,S是常数。我将使用数千种不同的p来表示S。这是一个搜索引擎,但内容不会改变。你考虑过lucene.net吗?不,我还没有。但从第一眼看,这似乎不是我想要的。我希望有一个轻量级的解决方案,尽可能减少外部依赖。最好是一个单独的小型C#class。