|
Posted by Vakayil Thobias on March 27, 2008, 12:42 am
Please log in for more thread options
> On Wed, 26 Mar 2008 16:37:32 +0530, Vakayil Thobias wrote:
>
>> Hello,
>>
>> I have to display the data from a file in tree structure(perl). The file
>> format is as follows(first field parent, second field child) :
>>
>> PM01 PM02
>> PM01 PM1A
>> PM02 PM03
>> PM03 PM04
>> PM04 PM05
>> PM04 PM06
>> PM1A PM1B
>> PM1A PM1C
>>
>> The output should be like this :
>> PM01 -- PM02 -- PM03 -- PM04 -- PM05
>> PM06
>> PM01 PM1A -- PM1B
>> PM1C
>>
>> Anybody have idea ?
>
> Something like (got a bit more complicated than I thought at first,
> someone is bound to come up with a better/shorter solution):
>
> #!/usr/bin/perl
>
> use strict;
> use warnings;
>
> # Note all the commented out debug code!
> #use Data::Dumper;
>
> # read in the file
> # remember both parent -> children and
> # child -> parent
>
> # Need to remember all children to print the tree
> my %children;
>
> # Need to remember all parents to find all roots
> my %parent;
>
> while (<DATA>) {
> my ($parent, $child) = split;
> die if exists $parent;
> $parent = $parent;
> push @}, $child;
> }
>
> #print Data::Dumper->Dump([\%parent], ["*parent"]), "\n";
> #print Data::Dumper->Dump([\%children], ["*children"]), "\n";
>
> # Get all nodes without a parent, those are the roots
> my @roots = grep { not exists $parent } keys %children;
> #print Data::Dumper->Dump(\@roots, ["*roots"]), "\n";
>
> # Print the tree
> for (@roots) {
> print "$_";
> print_children(1, $children );
> }
>
> # Print all children of the current node
> #
> # Parameters:
> # - $indent: The amount of nodes to indent
> # - $children_ref: reference to an array containing all children
> # or undef if there are no children.
> #
> sub print_children {
> my ($indent, $children_ref) = @_;
>
> # No children? Print a newline and quit this branch.
> unless ($children_ref) {
> print "\n";
> return;
> }
>
> # There are children, print each one on a new line,
> # with the proper indent. Use "+-" if more than one child,
> # use "--" if only one. That way we get a nice tree look.
> my @children = @$children_ref;
> my $sep = @children==1 ? "--" : "+-";
> my $first = 1;
> for (@children) {
> my $spaces = $first ? 0 : $indent*8-4;
> $first = 0;
> print " "x$spaces, " $sep ", $_;
> print_children($indent+1, $children);
> }
> }
>
> __DATA__
> PM01 PM02
> PM01 PM1A
> PM02 PM03
> PM03 PM04
> PM04 PM05
> PM04 PM06
> PM1A PM1B
> PM1A PM1C
>
> HTH,
> M4
Hello Martijn Lievaart,
Excellent solution.
It's really workign fine.
Thank you very much.
Regards,
Thobias
|