加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Perl:使用Algorithm :: Loops

发布时间:2020-12-16 06:22:47 所属栏目:大数据 来源:网络整理
导读:我正在尝试使用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
我正在尝试使用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";
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读