【问题标题】:How to efficiently find if a string contains a dictionary word?如何有效地查找字符串是否包含字典单词?
【发布时间】:2014-06-05 13:12:51
【问题描述】:

我有一个 URL 列表和一本字典。

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

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

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

基本上我正在寻找最直接的方法来构建这个正则表达式"word_1|..|word_n" where n=100.000

【问题讨论】:

    标签: regex unix


    【解决方案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 实际操作:

    grep -f dictionary.txt urls.txt
    

    输出:

    http://www.foo.com
    http://www.bar.com
    http://www.stackoverflow.com
    

    【讨论】:

    • GNU grep 允许搜索构成整个单词的匹配项。例如,在上面的示例中,“stackoverflow”被认为是一个单词,因此与“stack”不匹配。见gnu.org/software/grep/manual/grep.html中的“-w”
    • 请注意字典的格式,尤其是 unix 行尾与 windows 行尾。否则,它正在工作,但我不确定性能。我现在正在做一个基准测试。
    • grep -f 不适用于大型(100000 字)字典
    【解决方案2】:

    我不确定这会快多少,但它可能工作正常。

    我使用哈希来存储所有单词,然后搜索每个可能的单词。哈希搜索速度很快,因此它可能比 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
    

    【讨论】:

    • 您好,感谢您的 +1。你试过我的版本吗?我很想知道它是否更快。
    猜你喜欢
    • 2020-03-16
    • 2016-11-06
    • 1970-01-01
    • 1970-01-01
    • 2016-02-24
    • 2014-01-25
    • 2017-02-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多