脚本从wordlist中查找给定单词内的单词

时间:2012-10-10 23:35:09

标签: ruby parsing sed awk

我有一个250K字的词典(txt文件)。对于每一个单词,我想提出一个脚本,它将抛出所有可能的字谜(每个字谜也应该在字典中)。

理想情况下,脚本将以这种格式输出:

  

word1:anagram1,anagram2 ......

     

word2:anagram1,anagram2 ......

非常感谢任何帮助。

4 个答案:

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

this的启发,我建议您创建一个Trie

然后,具有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