On 07 Jan 03 at 09:54:13AM, Tim Dolezal wrote:
> If this is the wrong list for this question, can you please let me know
> whish list I should go to.
>
> My output should look something like this:
>
> a-\
> |-b
<snip>
> My data file has at least these two columns:
>
> Col1 Col2
> a
> b a
<snip>
> What is the best way to do this?
I wouldn't claim mine is the best solution, but it is reasonable. It
creates a hash of lists, where each node is a list of children for
that node. Then it starts at the root node and recursively prints out
the tree. I fiddled with different mechanisms for correctly printing
the lines that connect to later nodes, but I settled on simply
remembering a string to print ($indent).
----------
SCRIPT:
#!/usr/bin/perl -w
use strict;
my %tree;
while (my $line = <DATA>)
{
my ($item, $parent) = split /\s+/, $line;
push @{$tree{$parent}}, $item;
}
print_node("", "");
sub print_node
{
my ($key, $indent) = @_;
return unless exists $tree{$key};
my @children = @{$tree{$key}};
for (my $i = 0; $i < @children; ++$i)
{
my $child = $children[$i];
print "$indent| \n";
print "$indent\\-$child\n";
my $new_indent = $indent . (($i == @children - 1)? " ": "| ");
print_node($child, $new_indent);
}
}
__DATA__
a
b a
c b
d c
e c
f a
g d
h f
i f
j i
k i
l k
m a
OUTPUT:
|
\-a
|
\-b
| |
| \-c
| |
| \-d
| | |
| | \-g
| |
| \-e
|
\-f
| |
| \-h
| |
| \-i
| |
| \-j
| |
| \-k
| |
| \-l
|
\-m
TIM'S OUTPUT:
a-\
|-b
| |
| \-c
| |
| \-d
| | |
| | \-g
| |
| \-e
|
|-f
| |
| \-h
| |
| \-I
| |
| \-j
| |
| \-k
| |
| \-l
|
\-m
LIMITATIONS:
. It does not sort the child nodes in any way; it wouldn't be hard.
. It does not format the tree exactly as you have specified (although
your formatting for the root node is not consistent anyway). You might
want to put in a special case for the root node to avoid it appearing
to be a child of nothing.
. It is case-sensitive. Your data and output (i, I) suggest
case-insensitivity.
----------
Regards,
Ian