perl中的递归函数

时间:2016-05-02 09:27:17

标签: perl recursion

我有一个像

这样的文件
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++;

}

2 个答案:

答案 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