Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Lexicographic tree

by pierre.marchal (Novice)
on May 05, 2010 at 00:33 UTC ( [id://838420]=CUFP: print w/replies, xml ) Need Help??

Hi all,

I just finished this one-liner which builds a lexicographic tree and wanted to share it with the community.

perl -MStorable -ne 's/(.)/\{\1\}/g;eval("\$x${_}{EOS}");store(\%x,output)'

To print it in a human-readable way :

perl -MStorable -MData::Dumper -e 'print Dumper retrieve(output)'

Replies are listed 'Best First'.
Re: Lexicographic tree
by ambrus (Abbot) on May 05, 2010 at 08:32 UTC

    For searching purposes, this data structure is sometimes called a trie.

Re: Lexicographic tree
by ambrus (Abbot) on May 05, 2010 at 09:09 UTC

    I don't like your eval solution, so here are some alternatives. The first solution is yours, the second used the Data::Diver module, the third is just a plain loop.

    use warnings; use strict; use Data::Dump::Streamer; my @word = map { lc } qw" the in of to that "; # solution in OP my %x; for (my @w = @word) { s/(.)/\{\1\}/g; eval("\$x${_}{EOS}++"); } Dump(\%x); # module use Data::Diver "DiveVal"; my %y; for (@word) { DiveVal(\%y, split(//, $_), "EOS")++; } Dump(\%y); # by hand my %z; for (@word) { my $t = \%z; for my $k ($_ =~ /./gs) { $t = \%{$$t{$k}} } $$t{EOS}++; } Dump(\%z); __END__

    Output:

    \1 better written as $1 at a.pl line 10. $HASH1 = { i => { n => { EOS => 1 } }, o => { f => { EOS => 1 } }, t => { h => { a => { t => { EOS => 1 } }, e => { EOS => 1 } }, o => { EOS => 1 } } }; $HASH1 = { i => { n => { EOS => 1 } }, o => { f => { EOS => 1 } }, t => { h => { a => { t => { EOS => 1 } }, e => { EOS => 1 } }, o => { EOS => 1 } } }; $HASH1 = { i => { n => { EOS => 1 } }, o => { f => { EOS => 1 } }, t => { h => { a => { t => { EOS => 1 } }, e => { EOS => 1 } }, o => { EOS => 1 } } };

      Anyway, thanks for your contributions. I'll make one-liners out of those :)

        I'd make two minor adjustments to your one-liner plus one major one and fix one bug:

        perl -MStorable -ne 's/(.)/\{$1\}/g;eval­("\$x$_\{­EOS}=0");END{sto­re +(\%x,out­put)}' # (Perl not sed)^ prettier^^^ bug^^ ^^^^was quit +e wasteful

        Regarding

        I'll make one-liners out of those :)

        Just because it is a one-liner doesn't mean it has to suck as code (using string-eval like that). ;) The approaches I've used (for example in Re: find all paths of length n in a graph (Boggle solver)) fit easily as one-liners. I've replaced your 'EOS' with a more universal "end of" string, "\n".

        perl -MStorable -ne '$p=\%t;$p=$p->{$_}||={}for/./gs;END{sto­re(\%t,ou +t­put)}'

        That doesn't even autovivify.

        Here's another version for those who don't care about the 'store to file' step (with extra verbosity to overcome Data::Dumper's extremely ugly defaults and to provide sample input). Note that here I use an earlier approach of mine so I can have the end-of-word entry point to a false value instead of to an empty hash.

        grep '^s\?[hk]\?[ei][ln][tlk]y\?$' /usr/share/dict/words | perl -MData +::Dumper -ne '$p=\\%t;$p=\$$p->{$_}for/./gs;$$p=0;END{print Data::Dum +per->new([\%t])->Terse(1)->Indent(1)->Sortkeys(1)->Useqq(1)->Dump()}' + | less

        - tye        

      I think you didn't understand the purpose of my post. I'm talking about a perl one-liner.
      It goes without saying that I wouldn't use such approach in a proper perl program.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: CUFP [id://838420]
Approved by ww
Front-paged by Arunbear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (4)
As of 2024-04-20 14:50 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found