Perl:使用Algorithm :: Loops

前端之家收集整理的这篇文章主要介绍了Perl:使用Algorithm :: Loops前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试使用NestedLoops函数在Perl中构造一个排列程序.这是我的代码

use strict;
use warnings;
use Algorithm::Loops qw(NestedLoops);

my @a = 'a'..'o';

my $length = 5;
my $start = 0;
my $depth = 2;

NestedLoops([
  [0..$length],( sub {
    $start = 0 if $start == $depth;
    $start++;
    [$start * $length..$start * $length + $length - 1]
  }) x $depth,],\&permute,);

sub permute {
  my @ind = @_;
  foreach my $i (@ind) {
    print $a[$i];
  }
  print "\n";
}

所以我有一个数组,字母’a’到’o'(大小为15).我将数组视为有3行,所以我对数组的想象是这样的:

abcde
fghij
klmno

然后每个循环对应于每一行……我想构建如下的排列:

afk
afl
afm
afn
afo
agk  // fails here... I end up getting agg
...

它适用于前5个值(最低循环的整个运行),但是第二次运行失败,因为$start的最后一行的值被重置为0 ……这是一个问题,因为它会破坏一切.

所以我想知道的是,如何根据级别保持$start持久性的值…所以我要求的基本上是常量.我的循环真的应该是这样的:

for my $a (0..5) {        # 0 at this level and never change
  for my $b (5..10) {     # $start should be 5 at this level and never change
    for my $c (10..15) {  # $start should be 10 at this level and never change
      permute($a,$b,$c);
    }
  }
}

现在,因为我将有一个可变长度的for循环,我不能硬编码每个起始值,所以我正在寻找一种方法来初始创建这些起始值,然后在循环重置时保留它们.

我意识到这是一个令人困惑的问题,所以请提出问题,我将帮助澄清.

解决方法

你正在努力做到这一点.
部分问题是 NestedLoops的文档没有详细介绍如何使用第一个参数中的子例程引用.

对于以下示例,假设这是在它们上面的某处写的.

use strict;
use warnings;
use Algorithm::Loops qw'NestedLoops';

真的最简单的方法调用NestedLoops来获得你想要的东西是这样的:

NestedLoops(
  [
    ['a'..'e'],['f'..'j'],['k'..'o'],\&permute
);

sub permute {
  print @_,"\n";
}

如果你真的希望动态生成NestedLoops的参数,我建议使用List::MoreUtils part.

use List::MoreUtils qw'part';

my @a = 'a'..'o';

my $length = 5;
my $index;

NestedLoops(
  [
    part {
      $index++ / $length
    } @a
  ],"\n";
}

如果由于某种原因你想要将带有索引的NestedLoops调用到数组中,那么使用part仍然很容易.

use List::MoreUtils qw'part';

my @a = 'a'..'o';

my $length = 5;

NestedLoops(
  [
    part {
      $_ / $length
    } 0..@a-1
  ],\&permute
);

sub permute {
  print map { $a[$_] } @_;
  print "\n";
}

你遇到的主要问题是你给NestedLoops的两个子程序引用是修改相同的变量,它们都被多次调用.
解决此问题的最佳方法是依赖于调用子例程时的最后一个值. (从实现来看,这似乎更接近于它的使用方式.)

my @a = 'a'..'o';

my $length = 5;
my $depth = 3;

NestedLoops(
  [
    [0..$length-1],(sub{
      return  unless @_;
      my $last = pop;
      my $part = int( $last / $length ) + 1; # current partition
      my $start = $part * $length; # start of this partition
      my $end = $start + $length;
      [$start..$end-1] # list of variables in this partition
    }) x ($depth-1)
  ],\&permute
);

sub permute {
  print map { $a[$_] } @_;
  print "\n";
}

猜你在找的Perl相关文章