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

时间:2016-11-15 08:53:06

标签: 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', ... ] # contains ip addresses

我需要在巨大的日志文件中搜索它们......

感谢。

2 个答案:

答案 0 :(得分:2)

String#include?方法很方便,但如果你询问最有效(计算)效率的方法,你应该使用triez 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 }
}

您可以迭代列表中的所有单词,并非常有效地找到它们出现的行:

words = %w[lorem dolor elit foobar]
words.each do |word|
  t.search_with_prefix word do |suffix, line_number|
    position = lines[line_number].size - suffix.size - word.size
    puts "'#{word} occurs on line #{line_number}, position #{position}"
  end
end
#=> 'lorem occurs on line 0, position 0
#=> 'dolor occurs on line 0, position 12
#=> 'dolor occurs on line 3, position 13
#=> 'elit occurs on line 1, position 23

顺便说一下。下载网页后,Web搜索引擎所做的第一件事就是构建其后缀树。另一个对字符串搜索感兴趣的宝石是fast_trie

答案 1 :(得分:1)

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

  

在finit字母表Σ上给出两个字符串T和P.   字符串匹配问题是关于找到给定模式中出现给定模式P的所有有效移位(索引)T

因此,您可以将问题减少到字符串匹配问题,如下所示:

  1. 输入文件 - &gt;文本序列
  2. 数组中的项目 - &gt;模式序列
  3. 下表显示了一些字符串匹配算法,它们的预处理和匹配运行时。 设n = | T_1 | + | T_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)       |
    

    有关更多信息,您可以在以下链接https://www.youtube.com/watch?v=NinWEPPrkDQ下阅读Erick Domaine关于字符串算法的讲座,或阅读已知的算法入门书中的第32章“字符串匹配”[985 - 1013]根据CLRS。