遍历一个特里来得到所有的话

时间:2011-05-18 07:15:09

标签: perl data-structures traversal trie

我已经编写了Perl代码来实际创建一个 Trie 数据结构,给定一组数组中的单词。现在我在浏览和打印文字时遇到了问题。

还粘贴了创建的Datastructure的Dumper输出。

遍历之后的最后一组单词似乎并不正确,因为遍历逻辑肯定缺少某些东西。但是trie创作很好并且工作得很快。有人可以帮助我吗?

trie的顶级是哈希

  1. 每个哈希项都有一个键 字母和每个哈希指向一个 数组引用

  2. 数组ref再次包含一个 哈希列表和每个哈希项目是 与1

  3. 相同

    如果您在输出中看到第一个单词。它出现在 archtopriumwe

    我们应该得到 arc,arch,atop,atrium,awe

    CODE

    use Data::Dumper;
    my %mainhash;
    
    ## Subroutine
    sub storeword   {
        my $type = shift;
        my $fc = shift;
        my $word = shift;
        return if ((not defined $word) or (length($word) == 0));    
        my @letters =  split (//,$word);
        my $len = scalar(@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;
        for($i = 0;$i {$letters[0]}) {
                $flag =1;
                $pass_ref = $hashitem->{$letters[0]};
                last;
            }
        }
        if ($flag == 0) {
            $newitem->{$letters[0]} = [];   
            push(@$arr_ref,$newitem);
            $pass_ref = $newitem->{$letters[0]};
        }
    
        storeword($pass_ref,$letters[0],join ('',@letters[ 1..$len]));
    }
    
    ## Subroutine
    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$letter\n";
            }
        }
    }
    
    ##main
    
    ##list of words
    my @wd =  qw (arc atop awe blob boil fame tub arch atrium);
    
    ##inserting each word into the datastructure
    foreach my $w (@wd) {
        my @letters = split (//,$w);
        my $len = scalar(@letters) - 1;
        if (not exists $mainhash{$letters[0]})  {
            $mainhash{$letters[0]} = [];
        }
        storeword($mainhash{$letters[0]},$letters[0],join ('',@letters[ 1..$len])); 
    }
        print Dumper(%mainhash);
            ## Trying to print each word from trie.
        print("\n List of words\n");    
        process('',\%mainhash);
    
    
    

    输出:

    $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' => []
                         }
                       ]
              }
            ];
    
    List of words
    archtopriumwe
    bloboil
    fame
    tub
    
    

1 个答案:

答案 0 :(得分:3)

您是否看到您的代码只是打印一次数据结构中的每个字母,而不是每个字都打印一次?并且只为树中的每个顶级字母打印一次换行符,而不是每个单词一个?

要解决此问题,您需要将更多上下文传递给递归子。像这样:

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$letter\n";
        }
    }
}

print("\n List of words\n");
process('', \%mainhash);

这不会打印弧,因为您无法在数据结构中告知弧是单词,而是例如boi不是。每个字母的值需要提供两个东西:一个布尔指示符,这是一个单词的结尾,以及一个可能的后续字母及其子单元的列表。