Ruby 搜索包含数组项的行的最有效方法

Ruby 搜索包含数组项的行的最有效方法,ruby,Ruby,我有一个包含100项的数组。我还有一个包含一百万行的大文件,对于每一行,我想知道这100项中的每一项是否都包含在每一行中。搜索的最佳和有效方式是什么?现在,这是我的算法,它只是 open file do each line array.each do each item if line contains item found end end 项目示例: array = [ '10.10.10.10', '20.20.20.20

我有一个包含100项的数组。我还有一个包含一百万行的大文件,对于每一行,我想知道这100项中的每一项是否都包含在每一行中。搜索的最佳和有效方式是什么?现在,这是我的算法,它只是

open file do each line
     array.each do each item
          if line contains item
              found
     end
end
项目示例:

array = [ '10.10.10.10', '20.20.20.20', ... ] # contains ip addresses
我需要在巨大的日志文件中搜索它们

谢谢。

String#include?
方法很方便,但是如果您询问最(计算)有效的方法,您应该使用gem(
gem install triez
),它提供前缀和后缀树。例如:

file = <<~TEXT
  lorem ipsum dolor sit amet,
  consectetur adipiscing elit,
  sed do eiusmod tempor incididunt
  ut labore et dolore magna aliqua.
TEXT

lines = file.split "\n"

require 'triez' # if necessary, gem install triez

t = Triez.new
lines.each_with_index { |line, line_number|
  t.change_all( :suffix, line ) { line_number }
}

顺便说一句,网络搜索引擎在下载你的网页后做的第一件事就是构建它的后缀树。字符串搜索的另一个有趣之处是。

您感兴趣解决的一般问题是众所周知的字符串匹配问题。问题定义如下:

给定有限字母表上的两个字符串T和p∑. 字符串匹配问题是查找给定模式P在给定文本T中出现的所有有效移位(索引)

因此,您可以将问题简化为字符串匹配问题,如下所示:

  • 输入文件->文本序列
  • 数组中的项目->模式序列
  • 下表显示了一些字符串匹配算法及其预处理和匹配运行时。 设n=| T|u 1 |+| T|u 2 |+…+|T|i|和m=| p|1 |+| p|2 |+…+|p_j|

    | Algorithm          | Preprocessing time | Matching time       |
    |:-------------------|-------------------:|:-------------------:|
    | Naive              |        0           |     O((n - m + 1)m) |     
    | Rabin-Karp         |      Theta(m)      |    O((n - m + 1)m)  |   
    | Finite Automaton   |       O(m|∑|)      |     Theta(n)        |
    | Knuth-Morris-Pratt |      Theta(n)      |      Theta(n)       |
    

    有关更多信息,请参见以下链接下的Erick Domaine关于字符串算法的讲座,或阅读第32章,字符串匹配“[第985-1013页]在《CLRS下已知算法简介》一书中。

    既然这是一个Ruby问题,你能发布Ruby代码而不是伪代码吗?一些示例数据可能也会有帮助。将你的IP地址放入一个文件,然后运行
    grep-F-F IP地址日志文件
    我们需要更多信息。这个文件是否保存在RAM中?是否重复是任务还是单任务任务?是的,但是当被搜索的词位于字符串的中间(不是前缀或后缀)时,它会努力工作。实际上,<代码> TrIEZ < /Cord> GEM实现了后缀树,而后缀树,据我所知,被用来高效地找到长DNA序列中间的子串。我将尝试将样本代码组合在一起。@ SergioTulentsev,我认为诀窍在于,在长字符串的中间出现的每个子串都是S的前缀。长字符串的前缀。因此,只要你能有效地构造长字符串的后缀树(你可以使用Ukonnen的算法),你就可以使用它来查看感兴趣的单词是否是其任何成员的前缀。啊,这是一个有趣的想法。我不认为它是这样工作的
    | Algorithm          | Preprocessing time | Matching time       |
    |:-------------------|-------------------:|:-------------------:|
    | Naive              |        0           |     O((n - m + 1)m) |     
    | Rabin-Karp         |      Theta(m)      |    O((n - m + 1)m)  |   
    | Finite Automaton   |       O(m|∑|)      |     Theta(n)        |
    | Knuth-Morris-Pratt |      Theta(n)      |      Theta(n)       |