最有效的字符串搜索方法

时间:2014-02-19 13:38:32

标签: string search

假设我有数百万行唯一字符串分布在数百个文本文件(“数据集”)中。现在我想查看这些文本文件是否包含另一个文本文件(“tofind”)中列出的200万个唯一字符串中的任何一个。最有效的方法是什么?一些额外的应用程序特定信息:

  • 必须区分大小写
  • 要查找的字符串将与找到的字符串完全匹配(即,它不是子字符串)
  • “数据集”中的每个文本文件包含大约700K行,为50MB,但有些可能是几百MB。
  • 再次,“dataset”和“tofind”中的字符串都是唯一的。索引无济于事。
  • 没有必要能够实时搜索(即,当有人开始输入时)。我只想输出任何匹配文本文件,其中包含匹配项和找到的文件。
  • 我有32GB的RAM和一个i7 3930K

我的选择包括使用简单的命令行/批处理“findstr”等,或者可能在vbscript或c#中编写搜索程序(如果需要,可以使用Java或Python,但我不熟悉它们)。对于这个特定的应用程序,最有效的解决方案是什么?

2 个答案:

答案 0 :(得分:0)

如果你有足够的内存来将所有字符串从tofind加载到内存中,那么你可以创建一组对,键是字符串的长度,值是字符串集。将所有字符串从tofind加载到此结构中,方法是根据它们的长度存储它们:5个字符的字符串将存储在具有5作为键的对的值中,10个字符的字符串将存储在该对的值中将10作为关键(你可以使用与第一个字符相同的分组方式来改进它,但我不会在这里描述,因为我想以最简单的方式分享这个想法。)

然后您可以加载其他字符串并搜索它们的出现次数。例如,在您的对中搜索长度为10的字符串,其中10为关键字。

如果数据集的大小太大,那么您可以通过一次加载一批字符串然后清除结构并使用下一批重建它来完成相同的操作。

答案 1 :(得分:0)

由于您不必实时执行此操作,因此您可以获得很多优势 设计搜索过程。我没有仔细考虑过,但似乎是这样 我可以通过几个步骤完成这项工作:

第1步

消除您知道与任何字符串不匹配的数据集中的字符串 在 tofind 字符串列表中。 Bloom Filter是实现此目的的一种非常有效的方法。 它具有零假阴性率,即,如果布隆过滤器没有命中 然后没有任何字符串匹配,字符串可以被删除。

然后需要验证Bloom Filter上的字符串,以确保您没有 得到假阳性。 Bloom Filters容易出现误报。但是,如果你付钱 密切关注选择好的散列函数并分配足够大的过滤器, 假阳性率可能很低。

对于布隆过滤器上有点击的每个字符串,保存该字符串和位置 击中的字符串。此信息将传递到第2步。

第2步

验证Bloom Filter上的字符串。现在,您需要验证所有1M tofind 字符串 使用有效的精确字符串匹配函数。 Trie似乎是一个很好的候选人 功能。将 tofind 字符串加载到Trie中,然后从该位置开始搜索它 由Bloom Filter发现。在这一点上,你将要么命中,在这种情况下 找到匹配项,或者错过了Bloom Filter报告误报的情况。

注意:此过程假设步骤1可以从中消除大量字符串 数据集。如果您希望大多数数据集字符串在 tofind 中包含匹配项,那么 它可能不值得努力。