我有 n = 10,000,000字符串 s 的 S ,需要找到 S < sub> p ,包含 S 的字符串 s ,其中包含子字符串 p 。
当我使用C#时,使用LINQ这是一个非常简单的任务:
string[] S = new string[] { "Hello", "world" };
string p = "ll";
IEnumerable<string> S_p = S.Where(s => s.Contains(p));
如果 S 包含许多字符串(如上面提到的10,000,000个字符串),那么速度会非常慢。
构建某种索引以更快地检索 S p 。
为此任务索引 S 的最佳方法是什么?您是否在C#中有任何实现?
答案 0 :(得分:1)
这是一种方法:
1.创建一个字符串T = S[0] + sep_0 + S[1] + sep_1 + ... + S[n - 1] + sep_n-1
(其中sep_i
是一个唯一的字符,在任何S[j]
的{{1}}中都不会出现(如果字符集,它实际上可以是整数不够大))
2.为j
构建后缀树(可以在线性时间内完成)
3.对于每个查询字符串T
遍历后缀树(它需要Q
次)。然后所有可能的答案都将位于某个子树的叶子中。所以你可以遍历所有这些叶子。如果O(length(Q))
相当长,则此子树中的叶数可能远小于Q
。
4.如果n
非常短,则子树中的叶数可能非常大。这就是为什么你可以为短查询字符串使用另一种策略:预先计算Q
的所有短子串,并为每个子串存储一组索引。然后,您可以为给定的S[0] ... S[n - 1]
打印这些索引。很难说“短”在这里意味着什么,但它可以通过实验找到。