【问题标题】:Fast way to find strings in set of strings containing substring在包含子字符串的字符串集中查找字符串的快速方法
【发布时间】:2014-10-10 14:29:11
【问题描述】:

任务

我有一个 S 的集合 n = 10,000,000 个字符串 s 并且需要找到集合 Sp 包含字符串 sS 包含子字符串 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 个字符串),这会变得非常慢。

想法

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

问题

为这个任务索引 S 的最佳方法是什么?你有 C# 中的任何实现吗?

【问题讨论】:

  • 你的集合 S 是常数吗?有多少个不同的 p 与相同的 S 一起使用?
  • 是的,S 是常数。我将为 S 使用数千种不同的 p。这是一个搜索引擎,但内容不会改变。
  • 你考虑过 lucene.net 吗?
  • 不,我还没有。但乍一看,这似乎不是我想要的。我想要一个轻量级的解决方案,尽可能少的外部依赖。最好是一个单一的、小型的 C# 类。

标签: string algorithm indexing substring


【解决方案1】:

这是一种方法:
1. 创建一个字符串T = S[0] + sep_0 + S[1] + sep_1 + ... + S[n - 1] + sep_n-1(其中sep_i是一个唯一字符,对于任何j,它都不会出现在S[j]中(如果字符集不够大,它实际上可以是一个整数)。 2. 为T构建一个后缀树(可以在线性时间内完成)。
3.对每个查询字符串Q遍历后缀树(需要O(length(Q))时间)。然后所有可能的答案将位于某个子树的叶子中。所以你可以遍历所有这些叶子。如果Q 相当长,那么这个子树的叶子数很可能比n 少很多。
4. 如果Q 真的很短,那么子树中的叶子数可能会很大。这就是为什么您可以对短查询字符串使用另一种策略:预先计算 S[0] ... S[n - 1] 的所有短子字符串,并为每个短子字符串存储一组索引。然后,您可以为给定的Q 打印这些索引。在这里很难说“短”到底是什么意思,但可以通过实验找到。

【讨论】:

  • 我读过一些关于后缀树的文章,现在似乎建议使用 suffix arrays 代替。有什么是我监督的还是你同意的?
  • @user2033412 查找查询字符串的出现范围可以在后缀数组中的 O(length(Q) * log n) 中完成(不像后缀树中那样线性),除非您使用散列比较字符串,但总的来说后缀数组也是一个不错的选择。
  • sep_i = sep_j 可以适用于所有 ij 还是我需要不同的?
  • @user2033412 对于后缀树,它们肯定应该不同,对于所有i 使用相同分隔符的后缀数组看起来很好。
  • @user2033412 你仍然需要它。例如,如果您在不使用分隔符的情况下连接 aabb,您将得到 aabb 并最终在其中找到 ab,即使它不是其中任何一个的子字符串。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多