我有一个包含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
我需要在巨大的日志文件中搜索它们......
感谢。
答案 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
因此,您可以将问题减少到字符串匹配问题,如下所示:
下表显示了一些字符串匹配算法,它们的预处理和匹配运行时。 设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。