【问题标题】:What is the most efficient algorithm to find anagrams from a dictionary?从字典中查找字谜的最有效算法是什么?
【发布时间】:2018-03-26 18:59:20
【问题描述】:

我想创建一个散列:keys会首先遇到不同的单词,值是对anon数组的引用,带有这个key的变位词。

我编写了以下代码,当单词数量在范围内(0 到几千)时,它可以工作,但我想让它更快。

以下是我检查字符串是否为字谜的方法。我对所有单词和哈希的所有键进行迭代。

join("", sort(split (//, fc($word)))) eq join("", sort(split (//, fc($key)))))

【问题讨论】:

  • 明显的增强是只执行一次my $key = join( "", sort( split (//, fc($word) ) ) )。那应该有很大的不同。最重要的是,您可以预过滤字典中的单词以仅选择那些(例如)以原始单词中的两个字母开头的单词。
  • 查找字谜是“N 字母”问题的一种变体(N 个字母拼写 N 个或更少字母中的大多数其他单词)。最有效的解决方案之一是创建一个位直方图,其中第一个 32 位单词代表 a-z,第二层代表 a-z 的重复项……您很少需要查看第 4 层(这表示同一个字母出现 4 次) .通过将字典中的每个单词转换为其位直方图,您可以使用整数和比较来寻找匹配项,并在尽可能早的层拒绝。
  • 你能举个例子吗?
  • Apple 变为 10001000000100000000000000000000, 000000000000000100000000000000000。所有带有一个 a、一个 e、一个 l 和两个 p 的单词都将具有相同的模式。

标签: algorithm perl


【解决方案1】:

O(N)。

my %grouped;
while (<>) {
   chomp;
   my $key = sort split //, fc($_);
   push @{ $grouped{$key} }, $_;
}

my @anagrams = grep { @$_ >= 2 } values(%grouped);

【讨论】:

  • 也适合函数排序,它遍历字典并在我们可以填充哈希的地方有块。它工作得非常快。我很惊讶。
  • 我想你的意思是:my $key = join '', sort split //, CORE::fc($_);
  • fc vs CORE::fc 取决于您的 perl 版本是否 >= 5.16
  • @xxfelixxx、CORE::fcuse feature qw( fc );,任君选择
猜你喜欢
  • 2016-03-17
  • 2010-12-01
  • 1970-01-01
  • 2017-10-28
  • 2021-12-06
  • 2014-03-02
  • 2011-02-07
  • 2012-11-03
  • 2019-02-02
相关资源
最近更新 更多