如何有效地查找字符串是否包含字典单词?

时间:2014-06-05 13:12:51

标签: regex unix

我有一个网址列表和一个字典。

查找哪些网址至少包含字典中的一个字词的最有效方法是什么?该词典包含100.000个单词,我有700.000个要测试的URL。

您可以假设字典为/ usr / share / dict / american-english。

我假设正则表达式引擎将一个像word1|word2|..|wordn这样的表达式编译成一个有效的有限自动机,它在编译后以线性时间运行。

基本上我正在寻找构建此正则表达式"word_1|..|word_n"的最直接方法,其中n = 100.000

2 个答案:

答案 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