我有一个像
这样的文件abc->bcd, efg, hij
bcd->ijk, lmn, ipl
efg->kfg, iop, nkl
lmn->opq, stv, imn
应该从
创建嵌套输出abc
bcd
ijk
lmn
opq
stv
imn
ipl
efg
kfg
iop
nkl
hij
我不太确定如何在perl中使用递归函数来处理它,以找到任何级别的嵌套。任何人都非常感谢。
我尝试使用以下代码,但它只提供一个级别
my $k = 0;
while ($k <=$#array1)
{
if ($array1[$k]=~m/(.[^->]*)->(.[^\n]*)/)
{
$val = $1;
$val1 = $2;
push @check, $val;
print $val;
my @array2=split /,/,$val1;
foreach my $newid (@array2)
{
push @check1, $newid;
print $newid, "\n";
}
}
$k++;
}
答案 0 :(得分:4)
它是另一张有向图!他们最近似乎很受欢迎
您需要Graph
模块,它允许您构建 edge 和 vertices (节点和连接)树,然后遍历它以获取你的打印输出
此程序与您的示例数据完全相同。构建图形后,我测试它是否循环以避免无限循环,然后为所有源顶点调用我的递归子例程print_vertex
源顶点是具有后继者但没有前辈(子节点但没有父节点)的顶点。所以它是树的根。我已经使用for
循环,以防数据有多个根,但您的数据只有一个这样的顶点:abc
use strict;
use warnings 'all';
use feature 'say';
use Graph;
my $g = Graph->new(directed => 1);
while ( <DATA> ) {
my ($from, @to) = /[^\s>,-]+/g;
$g->add_edge($from, $_) for @to;
}
if ( my @cycle = $g->find_a_cycle ) {
die sprintf "Graph contains a cycle: %s\n", join(' >> ', @cycle, $cycle[0]);
}
print_vertex($_) for $g->source_vertices;
sub print_vertex {
my ($v, $indent) = (@_, 0);
printf "%s%s\n", ' ' x $indent, $v;
print_vertex($_, $indent+1) for $g->successors($v);
}
__DATA__
abc->bcd, efg, hij
bcd->ijk, lmn, ipl
efg->kfg, iop, nkl
lmn->opq, stv, imn
abc
efg
iop
kfg
nkl
bcd
lmn
stv
opq
imn
ijk
ipl
hij
答案 1 :(得分:1)
...当我尝试这个时,输出中的订单已经改变了......你能吗? 帮助我如何保留订单?
纯Perl sans模块中的递归解决方案:
use strict;
use warnings;
my %children;
my $patriarch;
while (<DATA>) {
chomp;
my ($parent, @children) = split /[->, ]+/;
$children{$parent} = \@children;
$patriarch = $parent unless defined $patriarch;
}
sub print_family {
my ($parent, $indentation) = (@_, '');
print($indentation, $parent, "\n");
if (exists($children{$parent})) {
foreach my $child (@{$children{$parent}}) {
&print_family($child, $indentation . "\t");
}
}
}
&print_family($patriarch)
__DATA__
abc->bcd, efg, hij
bcd->ijk, lmn, ipl
efg->kfg, iop, nkl
lmn->opq, stv, imn
产地:
abc
bcd
ijk
lmn
opq
stv
imn
ipl
efg
kfg
iop
nkl
hij