我有一个网址列表和一个字典。
查找哪些网址至少包含字典中的一个字词的最有效方法是什么?该词典包含100.000个单词,我有700.000个要测试的URL。
您可以假设字典为/ usr / share / dict / american-english。
我假设正则表达式引擎将一个像word1|word2|..|wordn
这样的表达式编译成一个有效的有限自动机,它在编译后以线性时间运行。
基本上我正在寻找构建此正则表达式"word_1|..|word_n"
的最直接方法,其中n = 100.000
答案 0 :(得分:1)
您可以尝试使用grep
。示例数据:
$ cat urls.txt
http://www.foo.com
http://www.google.com
http://www.bar.com
http://www.stackoverflow.com
$ cat dictionary.txt
foo
buz
bar
bez
stack
Grep in action:
grep -f dictionary.txt urls.txt
输出:
http://www.foo.com
http://www.bar.com
http://www.stackoverflow.com
答案 1 :(得分:1)
我不确定这会有多快,但可能会有效。
我使用哈希来存储所有单词,然后搜索每个可能的单词。哈希搜索速度很快,因此它可能比grep更好。 (可能不是 - 谁知道grep里面有什么黑魔法!)
#!/usr/bin/perl
use warnings;
use strict;
# Build a hash containing all the words.
open FILE, '/usr/share/dict/words';
my %dict;
foreach (<FILE>) {
chomp;
$dict{$_} = 1;
}
# Function to test if a string has words.
sub haswords {
my $_ = shift;
my @list = split '';
for (my $i=0; $i<=$#list; $i++) {
for (my $j=$i+1; $j<=$#list; $j++) {
my $word = join('', @list[$i .. $j]);
if (defined($dict{$word})) {
return 1;
}
}
}
}
# Test it.
foreach (<>) {
chomp;
if (haswords($_)) {
print "$_ has words\n";
} else {
print "$_ no words\n";
}
}
输出:
yeshaswords has words
kakalkdkak has words
vvvvvvvv no words