/ / Atravessando um trie para obter todas as palavras - perl, estruturas de dados, travessia, trie

Atravessando um trie para obter todas as palavras - perl, estruturas de dados, traversal, trie

Eu escrevi código Perl para realmente criar um Trie Datatructure dado um conjunto de palavras em uma matriz. Agora tenho problemas para percorrer e imprimir as palavras.

Também colei a saída do Dumper da estrutura de dados criada.

O conjunto final de palavras após a travessia não parece estar certo já que a lógica da travessia certamente está faltando alguma coisa. Mas a criação está bem e funciona rápido. Alguém pode me ajudar aqui?

O nível superior do trie é um hash

  1. Cada item hash tem uma chave que é um carta e cada hash aponta para um array ref.

  2. Array ref again contém um lista de hashes e cada item hash é o mesmo que 1

Se você vir a primeira palavra na saída. Surge como archtopriumwe.

Nós devemos pegar arco, arco, sobre, átrio

CÓDIGO

use Data ::Dumper; meu% mainhash;  ## Sub-rotina sub storeword { meu $ type = shift; meu $ fc = shift; minha $ word = shift; return if ((não definido $ word) ou (length ($ word) == 0)); meu @letters = split (//, $ word); meu $ len = escalar (@letters) - 1; my ($ arr_ref, $ pass_ref, $ flag, $ i, $ hashitem, $ newitem); $ pass_ref = $ hashitem = $ new_item = undef; $ arr_ref = $ type; $ setstop = 1 if (length ($ word) == 1); $ flag = 0; para ($ i = 0; $ i {$ letters [0]}) { $ flag = 1; $ pass_ref = $ hashitem -> {$ letras [0]}; último; } } if ($ flag == 0) { $ newitem -> {$ letras [0]} = []; push (@ $ arr_ref, $ newitem); $ pass_ref = $ newitem -> {$ letras [0]}; }  storeword ($ pass_ref, $ letters [0], join ("", @ letras [1 .. $ len])); }  ## Sub-rotina subprocesso { meu ($ prefixo, $ trie) = @_; para minha carta $ (chaves de classificação% $ trie) { if (@ {$ trie -> {$ carta}}) { para minha ramificação $ (@ {$ trie -> {$ letter}}) { process ("$ prefix $ letter", $ branch); } } outro { print "$ prefixo $ lettern"; } } }  ##a Principal  ## lista de palavras my @wd = qw (arco em cima de blobs de admiração fervura fama tub arco átrio);  ## inserindo cada palavra na estrutura de dados foreach meu $ w (@wd) { meu @letters = split (//, $ w); meu $ len = escalar (@letters) - 1; if (não existe $ mainhash {$ letras [0]}) { $ mainhash {$ letras [0]} = []; } storeword ($ mainhash {$ letras [0]}, $ letras [0], join ("", @ letras [1 .. $ len])); } impressão Dumper (% mainhash); ## Tentando imprimir cada palavra de trie. print ("n Lista de palavrasn"); processo ("",% mainhash);


Saída:

$ VAR1 = "a"; $ VAR2 = [ { "r" => [ { "c" =>[ { "h" => [] } ] } ] } { "t" => [ { "o" => [ { "p" => [] } ] } { "r" => [ { "i" => [ { "u" => [ { "m" => [] } ] } ] } ] } ] } { "w" => [ { "e" => [] } ] } ]; $ VAR3 = "b"; $ VAR4 = [ { "l" => [ { "o" => [ { "b" => [] } ] } ] } { "o" => [ { "i" => [ { "l" => [] } ] } ] } ]; $ VAR5 = "f"; $ VAR6 = [ { "a" => [ { "m" => [ { "e" => [] } ] } ] } ]; $ VAR7 = "t"; $ VAR8 = [ { "u" => [ { "b" => [] } ] } ];  Lista de palavras archtopriumwe bloboil fama banheira

Respostas:

3 para resposta № 1

Você vê que seu código está apenas imprimindocada letra na estrutura de dados uma vez, em vez de uma vez por palavra em que está? E só imprimindo uma nova linha uma vez para cada letra de nível superior na árvore, não uma por palavra?

Para corrigir isso, você precisa passar mais algum contexto para o seu sub recursivo. Algo assim:

sub process {
my ($prefix, $trie) = @_;
for my $letter (sort keys %$trie) {
if ( @{ $trie->{$letter} } ) {
for my $branch (@{ $trie->{$letter} }) {
process("$prefix$letter", $branch);
}
}
else {
print "$prefix$lettern";
}
}
}

print("n List of wordsn");
process("", %mainhash);

Isso não imprime arco, porque você não fornecemaneira de dizer em sua estrutura de dados que é uma palavra, mas por exemplo boi não é. O valor de cada letra precisa fornecer duas coisas: um indicador booleano de que este é o fim de uma palavra e uma lista de possíveis letras a seguir e sua subtrime.