我有一个250K字的词典(txt文件)。对于每一个单词,我想提出一个脚本,它将抛出所有可能的字谜(每个字谜也应该在字典中)。
理想情况下,脚本将以这种格式输出:
word1:anagram1,anagram2 ......
word2:anagram1,anagram2 ......
非常感谢任何帮助。
答案 0 :(得分:1)
一定是字谜周。
我将向您推荐我之前提出的问题:https://stackoverflow.com/a/12811405/128421。它显示了如何构建哈希以快速搜索具有共同字母的单词。
为了您的目的,找到子串/内部词,您还需要找到可能的内部词。以下是如何基于起始单词快速定位不同大小的字母的独特组合:
word = 'misses'
word_letters = word.downcase.split('').sort
3.upto(word.length) { |i| puts word_letters.combination(i).map(&:join).uniq }
eim
eis
ems
ess
ims
iss
mss
sss
eims
eiss
emss
esss
imss
isss
msss
eimss
eisss
emsss
imsss
eimsss
一旦你有这些组合,拆分它们(或者不要做join
)并在我之前建立的答案中查找哈希。
答案 1 :(得分:1)
然后,具有N个级别的trie将具有所有可能的字谜(其中N是原始单词的长度)。现在,为了获得不同大小的单词,我建议你简单地遍历trie,即。对于所有3个字母的子字,只需在trie中制作3级深度的所有字符串。
我不是很确定这一点,因为我没有对此进行测试,但这是一个有趣的挑战,这个建议就是我将如何开始解决它。
希望它有点帮助=)
答案 2 :(得分:0)
h = Hash.new{[]}
array_of_words.each{|w| h[w.downcase.chars.sort].push(w)}
h.values
答案 3 :(得分:0)
到目前为止我在Perl
中尝试了什么:
use strict;
use warnings;
use Algorithm::Combinatorics qw(permutations);
die "First argument should be a dict\n" unless $ARGV[0] or die $!;
open my $fh, "<", $ARGV[0] or die $!;
my @arr = <$fh>;
my $h = {};
map { chomp; $h->{lc($_)} = [] } @arr;
foreach my $word (@arr) {
$word = lc($word);
my $chars = [ ( $word =~ m/./g ) ];
my $it = permutations($chars);
while ( my $p = $it->next ) {
my $str = join "", @$p;
if ($str ne $word && exists $h->{$str}) {
push @{ $h->{$word} }, $str
unless grep { /^$str$/ } @{ $h->{$word} };
}
}
if (@{ $h->{$word} }) {
print "$word\n";
print "\t$_\n" for @{ $h->{$word} };
}
}
END{ close $fh; }
速度可能会有一些改进,但它确实有效。
我使用words
archlinux
包中的French dict。
示例强>
$ perl annagrammes.pl /usr/share/dict/french
abaissent
absentais
abstenais
abaisser
baissera
baserais
rabaisse
(...)
注意强> 要安装perl模块:
cpan -i Algorithm::Combinatorics