Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl:使用算法::循环_Perl_For Loop - Fatal编程技术网

Perl:使用算法::循环

Perl:使用算法::循环,perl,for-loop,Perl,For Loop,我试图使用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;

我试图使用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个值(最低for循环的整个运行),但第二次运行失败,因为最后一行的值
$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);
    }
  }
}
NestedLoops(
  [
    ['a'..'e'],
    ['f'..'j'],
    ['k'..'o'],
  ],
  \&permute
);

sub permute {
  print @_, "\n";
}
现在,因为我将有一个可变长度的for循环,我不能硬编码每个起始值,所以我正在寻找一种方法来最初创建这些起始值,然后在循环重置时保留它们


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

你让这件事变得更加困难。
部分问题在于,的文档没有详细说明如何使用第一个参数中的子例程引用


对于以下示例,假设这是写在它们上面的某个地方

use strict;
use warnings;
use Algorithm::Loops qw'NestedLoops';
实际上,打电话获取所需信息的最简单方式如下:

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);
    }
  }
}
NestedLoops(
  [
    ['a'..'e'],
    ['f'..'j'],
    ['k'..'o'],
  ],
  \&permute
);

sub permute {
  print @_, "\n";
}
如果您确实希望动态生成参数,我建议使用from

如果出于某种原因,您希望使用索引调用数组,那么使用它仍然很容易

实际上,您遇到的主要问题是,您提供给的两个子例程引用正在修改相同的变量,并且它们都被多次调用。 解决此问题的最佳方法是依赖于调用子例程时给出的最后一个值。(从实现的角度来看,这似乎更接近于它的用途。)


使用子例程生成循环范围时,每次必须启动一个嵌套循环时都会调用该子例程。这意味着对于包含循环的每个迭代一次。在每次调用之前,$\uu被设置为包含循环变量的当前值,并且所有包含循环变量的值都作为参数传递

为了澄清这一点,您编写的
NestedLoops
语句相当于

sub loop_over {
  $start = 0 if $start == $depth;
  $start++;
  [$start * $length..$start * $length + $length - 1]
};

NestedLoops([
  [0..$length],
  (\&loop_over) x $depth,
], \&permute,);
在原始Perl中,它看起来像

for my $i (0 .. $length) {

  $_ = $i;
  my $list = loop_over($i);

  for my $j (@$list) {

    $_ = $j;
    my $list = loop_over($i, $j);

    for my $k (@$list) {
      permute($i, $j, $k);
    }
  }
}
因此,现在您对
$start
的计算是错误的,这一点也许更清楚了?在执行提升以重新启动包含循环之前,将对最内层进行多次重新评估

由于传递给子例程的参数由包含循环变量的所有值组成,因此可以检查
@
的大小,以查看生成范围的循环级别。例如,在上面的代码中,如果
@
包含两个值,它们是
$i
$j
,则必须返回
$k
的值;或者,如果只有一个参数,则它是
$i
的值,并且返回的值必须是
$j
的范围。因此,
$start
的正确值只是
@
中的元素数,可以使用
my$start=@

使用此方法,子例程也可以返回最外层循环的范围。代码如下所示

use strict;
use warnings;

use Algorithm::Loops qw(NestedLoops);

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

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

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

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

明亮的我无法正确下载和安装MoreUtils。。。关于
未定义的符号:Perl_Istack_sp_ptr
(我稍后将对此进行研究),我遇到了一些错误,但您的最后一段代码更符合我要查找的内容——只是因为我的数组将是随机字母,而不是按“a”-“o”的顺序排列。我想,如果我能以“a”-“o”的价格买到它,就不难适应了。非常感谢你的帮助!实际上,我也忽略了你的第一段代码。。。这样更优雅。如果我只是在我自己的数组中替换,它就可以完美地工作。可靠的回答。谢谢,我刚刚确认了莫鲁蒂尔也能用。说真的,谢谢。我不认为我可以要求一个更好的解决方案。我只是意识到我可以用
$\uu
替换我最后一个代码块中的
$last
use strict;
use warnings;

use Algorithm::Loops qw(NestedLoops);

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

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

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

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