gpt4 book ai didi

珀尔;如何避免严重嵌套的 foreach 循环

转载 作者:行者123 更新时间:2023-12-03 18:44:02 27 4
gpt4 key购买 nike

我想循环遍历 12 个字符串,并列出它们的每个组合,例如我缩短了 3 个术语的工作代码:

foreach my $t1 ('a', 0) {
foreach my $t2 ('b', 0) {
foreach my $t3 ('c', 0) {
my @terms = grep {$_ ne '0'} ($t1, $t2, $t3);
say join ('+', @terms);
}
}
}

哪个输出
a+b+c
a+b
a+c
a
b+c
b
c

这是正确的输出。

但是,我意识到 foreach 的深层嵌套循环不是好的编码习惯。

我在 Alternate looping nested foreach loops 中查看了替代方案但这要求这也很丑陋:
my @t1 = ("a", (0) x 132);
my @t2 = ("b", (0) x 132);
my @t3 = ("c", (0) x 132);
my @t4 = ("d", (0) x 132);
my @t5 = ("e", (0) x 132);
my @t6 = ("f", (0) x 132);
my @t7 = ("g", (0) x 132);
my @t8 = ("h", (0) x 132);
my @t9 = ("i", (0) x 132);
my @t10 = ("j", (0) x 132);
my @t11 = ("k", (0) x 132);
my @t12 = ("l", (0) x 132);

my $it = each_array(@t1, @t2, @t3, @t4, @t5, @t6, @t7, @t8, @t9, @t10, @t11, @t12);
while (my ($t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12) = $it->()) {
my @terms = grep {$_ ne '0'} ($t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8, $t9, $t10, $t11, $t12);
say join ('+', @terms);
}

这只是输出空格,似乎没有做我认为的 each_array应该做。我什至不确定会有 132 次迭代。

如何在没有 foreach 循环深度嵌套的情况下完成这 12 个术语?

最佳答案

您正在寻找非空子集。

当您有任意数量的嵌套循环时,您可以使用 Algorithm::LoopsNestedLoops .

use Algorithm::Loops qw( NestedLoops );

my @syms = 'a'..'c';
#my @syms = 'a'..'l';

NestedLoops(
[ map [ $_, undef ], @syms ],
sub {
@_ = grep defined, @_;
say join "+", @_ if @_;
}
);
NestedLoops也可用于生成迭代器。
my $iter = NestedLoops([
map [ $_, undef ], @syms
]);
while ( my @subset = $iter->() ) {
@subset = grep defined, @subset;
say join "+", @subset if @subset;
}

Algorithm::Combinatoricssubsets是针对此问题的专门解决方案。
use Algorithm::Combinatorics qw( subsets );

my $syms = [ 'a'..'c' ];
#my $syms = [ 'a'..'l' ];

my $iter = subsets($syms);
while ( my $subset = $iter->next() ) {
say join "+", @$subset if @$subset;
}

感谢@larsen 提出这种方法。

这个问题的解决方案可以简单地通过计数到 2N-1 来实现,每个位表示一个符号的存在或不存在。
my @syms = 'a'..'c';
#my @syms = 'a'..'l';

my @masks = map { 1 << $_ } 0..$#syms;

for my $n ( 1 .. 2**@syms-1 ) {
say join "+", map { $n & $masks[$_] ? $syms[$_] : () } 0..$#syms;
}

关于珀尔;如何避免严重嵌套的 foreach 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61938718/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com