我使用以下代码生成排列的所有可能组合并将其存储在@apirirow中,这适用于小$ globstring,但对于大输入会产生null @apirirow。我该如何解决这个问题?
$globstring = join ',', @distinctelements;
@apriorirow = glob "{$globstring}" x $i;
print "$globstring";
答案 0 :(得分:3)
使用glob
生成的内容既不是组合也不是排列,而是Cartesian product(也称为交叉产品)。将笛卡尔积存储在数组中将为大量输入数据使用大量内存。您可以使用Set::CrossProduct一次迭代笛卡尔积一个元组:
use Set::CrossProduct;
my $rows = 3;
my @elements = qw(a b c);
my @array;
push @array, \@elements for 1..$rows;
my $iterator = Set::CrossProduct->new(\@array);
while (my $tuple = $iterator->get) {
say join ',', @$tuple;
}
a,a,a
a,a,b
a,a,c
a,b,a
a,b,b
a,b,c
a,c,a
a,c,b
a,c,c
b,a,a
b,a,b
b,a,c
b,b,a
b,b,b
b,b,c
b,c,a
b,c,b
b,c,c
c,a,a
c,a,b
c,a,c
c,b,a
c,b,b
c,b,c
c,c,a
c,c,b
c,c,c
当然,您也可以使用glob
进行迭代:
perl -wE 'say while glob "{a,b,c}" x 3'
基本上会做同样的事情。但我发现Set :: CrossProduct的意图更清晰,而更喜欢使用数组而不是逗号分隔的字符串(更不用说附加功能了Set :: CrossProduct就像在下一个元组中偷看而没有实际迭代)。