Click here to get back home

display in a tree structure

 HomeNewsGroups | Search | About
 comp.lang.perl.misc    Post an article   get this group's latest topics as an RSS feed add this group's latest topics to your My MSN content add this group's latest topics to your My Yahoo content
Subject Author Date
display in a tree structure Vakayil Thobias 03-26-2008
Posted by Vakayil Thobias on March 26, 2008, 7:07 am
Please log in for more thread options
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 ?

Regards,
Thobias



Posted by Sandy on March 26, 2008, 10:46 am
Please log in for more thread options
On 26 Mar, 04:07, "Vakayil Thobias" <vakayil.thob...@alcatel-
lucent.com> wrote:
>
> 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
> PM01 PM1A -- PM1B

There is a very nice package:
http://search.cpan.org/~jhi/Graph-0.84/lib/Graph.pod

use Graph;
my $g = Graph->new();
$g->add_edge('a', 'b');
$g->add_edge('a', 'c');
$g->add_edge('b', 'd');
$g->add_edge('c', 'e');

There are additional packages for traversal:
http://search.cpan.org/~jhi/Graph-0.84/lib/Graph/Traversal.pm
http://search.cpan.org/~jhi/Graph-0.84/lib/Graph/Traversal/BFS.pm -
Breadth first
http://search.cpan.org/~jhi/Graph-0.84/lib/Graph/Traversal/DFS.pm -
Depth first

Or you can traverse it yourself by starting at the root and calling
$root->successors() and then call the same method for every element in
the returned list and print edges in the format you want.

Good luck

/sandy
http://myperlquiz.com/

Posted by Martijn Lievaart on March 26, 2008, 7:19 pm
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

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



Similar ThreadsPosted
What is the best way to make a Tree Data Structure in one text file? August 19, 2004, 6:49 pm
change tree structure file to rank-order file December 2, 2005, 9:23 am
Tree View July 3, 2005, 10:59 pm
Call tree for perl? November 30, 2004, 2:12 pm
XML::Smart, how to print out tree January 9, 2005, 6:42 pm
Expanding tree paths July 19, 2005, 10:48 am
Build Balanced Tree November 5, 2005, 7:25 pm
the use of removeChild() in Tree::Simple June 23, 2007, 8:18 am
File::Find and tree copying June 1, 2005, 4:21 pm
Tree view of directory while using Subversion November 13, 2005, 4:59 pm

Our other projects:

Art Dolls, Fairies and Mermaids - Sunnyfaces.net

Roy's Linux, Programming and Search Engines messages

1-Script XML SitemapXML Sitemap