File Coverage

blib/lib/Text/Trie.pm
Criterion Covered Total %
statement 38 38 100.0
branch 15 22 68.1
condition 4 6 66.6
subroutine 3 3 100.0
pod 2 2 100.0
total 62 71 87.3


line stmt bran cond sub pod time code
1             package Text::Trie;
2              
3 1     1   7716 use integer;
  1         11  
  1         5  
4             require 5.000;
5             require Exporter;
6              
7             @ISA = qw(Exporter);
8             @EXPORT_OK = qw(Trie walkTrie);
9              
10             $step = 1 unless defined $step; # Length of unit. All the arguments should
11             # have length that is multiple of this.
12             # Length of any cell in trie will be multiple
13             # too.
14              
15             sub Trie {
16 8     8 1 70 my @list = @_;
17 8 50       20 return shift if @_ == 1;
18 8         9 my %first;
19             my @ans;
20 8         12 foreach (@list) {
21 24         35 $c = substr $_, 0, $step;
22 24 100       65 $first{$c} = [] unless defined $first{$c};
23 24         25 push @{$first{$c}}, $_;
  24         59  
24             }
25 8         22 foreach (keys %first) {
26             # Find common substring
27 17         32 my $substr = $first{$_}->[0];
28 17 100       16 (push @ans, $substr), next if @{$first{$_}} == 1;
  17         53  
29 5         11 $l = length($substr) / $step * $step;
30 5         6 foreach (@{$first{$_}}) {
  5         10  
31 12         42 $l -= $step while substr($_, 0, $l) ne substr($substr, 0, $l);
32             }
33 5         9 $substr = substr $substr, 0, $l;
34             # Return value
35 5         6 @list = map {substr $_, $l} @{$first{$_}};
  12         32  
  5         9  
36 5         27 push @ans, [$substr, Trie(@list)];
37             }
38 8         47 @ans;
39             }
40              
41             sub walkTrie {
42 8     8 1 58 my ($singlesub,$headsub,$notsinglesub,$sepsub,$opensub,$closesub,@trie) = @_;
43 8         10 my $num = 0;
44 8         13 foreach (@trie) {
45 17 100 66     87 &$sepsub($_) if $num++ and defined $sepsub;
46 17 100 66     80 if (defined ref $_ and ref $_ eq 'ARRAY') {
47 5 50       28 &$opensub($_) if defined $opensub;
48 5 50       26 &$headsub(@$_[0]) if defined $headsub;
49 5 50       20 if ($#$_ > 1) {
50 5 50       16 &$notsinglesub($_) if defined $notsinglesub;
51 5         20 walkTrie($singlesub, $headsub, $notsinglesub, $sepsub, $opensub,
52 5         16 $closesub, @{$_}[1 .. $#$_]);
53             }
54 5 50       35 &$closesub($_) if defined $closesub;
55             } else {
56 12 50       33 &$singlesub($_) if defined $singlesub;
57             }
58             }
59             }
60              
61             1;
62             __END__