#!/usr/bin/perl -w package Tnode; sub new { my( $class, $word, $count ) = @_; my $self = {}; $self->{word} = $word; $self->{count} = $count; $self->{left} = undef; $self->{right} = undef; return bless $self, $class; } package main; die unless @ARGV; my $root = undef; while(<>) { chomp; $word = $_; $root = tree( $root, $word ); } treeprint( $root ); sub tree { my( $node, $word ) = @_; if( ! $node ) { $node = Tnode->new( $word, 1 ); $node->{left} = undef; $node->{right} = undef; } elsif( $node->{word} eq $word ) { $node->{count}++; } elsif( $word lt $node->{word} ) { $node->{left} = tree( $node->{left}, $word ); } else { $node->{right} = tree( $node->{right}, $word ); } return $node; } sub treeprint { my( $root ) = shift; if( $root ) { treeprint( $root->{left} ); printf( "%4d %s\n", $root->{count}, $root->{word} ); treeprint( $root->{right} ); } } #### #!/usr/bin/perl -w use Inline C; package Tnode; sub new { my( $class, $word, $count ) = @_; my $self = {}; $self->{word} = $word; $self->{count} = $count; $self->{left} = undef; $self->{right} = undef; return bless $self, $class; } package main; die unless @ARGV; my $root = undef; while(<>) { chomp; $word = $_; $root = tree( $root, $word ); } treeprint( $root ); sub tree { my( $node, $word ) = @_; if( ! $node ) { $node = Tnode->new( $word, 1 ); $node->{left} = undef; $node->{right} = undef; } elsif( $node->{word} eq $word ) { $node->{count}++; } elsif( $word lt $node->{word} ) { $node->{left} = tree( $node->{left}, $word ); } else { $node->{right} = tree( $node->{right}, $word ); } return $node; } __END__ __C__ void treeprint( SV *root ) { HV* hash; HE* hash_entry; SV* node; SV* word; SV* count; if( !SvROK(root) ) return; hash = (HV*)SvRV(root); node = get_child( hash, "left" ); if( node != NULL ) { treeprint( node ); } output( hash ); node = get_child( hash, "right" ); if( node != NULL ) { treeprint( node ); } } SV *get_child( HV *hash, char *key ) { int num_keys, i; HE *hash_entry; SV *sv_key; SV *sv_val; num_keys = hv_iterinit(hash); for (i = 0; i < num_keys; i++) { hash_entry = hv_iternext(hash); sv_key = hv_iterkeysv(hash_entry); sv_val = hv_iterval(hash, hash_entry); if( strcmp( SvPV( sv_key, PL_na), key ) == 0 ) { return( sv_val ); } } sv_val = NULL; return sv_val; } void output( HV *hash ) { int num_keys, i; HE *hash_entry; SV *sv_key; SV *sv_val; int count; char *word = NULL; num_keys = hv_iterinit(hash); for(i = 0; i < num_keys; i++) { hash_entry = hv_iternext(hash); sv_key = hv_iterkeysv(hash_entry); sv_val = hv_iterval(hash, hash_entry); if( strcmp( SvPV( sv_key, PL_na), "word" ) == 0 ) { word = SvPV( sv_val, PL_na); } if( strcmp( SvPV( sv_key, PL_na), "count" ) == 0 ) { count = SvIV( sv_val ); } } if( word ) { printf( "%4d %s\n", count, word ); } } #### Benchmark: timing 50000 iterations of inline, perl... inline: 13 wallclock secs (12.42 usr + 0.00 sys = 12.42 CPU) @ 4025.76/s (n=50000) perl: 12 wallclock secs (12.27 usr + 0.00 sys = 12.27 CPU) @ 4074.98/s (n=50000)