我注意到 Math :: Cartesian ::产品 返回一系列有福的物体,而不是简单的数组。我不知道为什么。实际上,我需要做一些额外的工作(不熟悉)才能使用结果...

有帮助吗?

解决方案

一种选择是模块 设置::交叉生产, ,它将产生普通的,未弄式的数组参考:

use Set::CrossProduct;
my $iter = Set::CrossProduct->new([ \@foo, \@bar ]);

while (my $tuple = $iter->get){
    ...
}

或立即获取所有元组:

my @tuples = $iter->combinations;

其他提示

我添加了一个 cartesian 功能 列表:: gen 最近:

  • cartesian CODE LIST_of_ARRAYREF

    cartesian 计算任何数量的数量阵列参考的笛卡尔产品,每个参考都可以是任何尺寸。返回发电机

    use List::Gen 'cartesian';
    my $product = cartesian {$_[0] . $_[1]} [qw/a b/], [1, 2];
    print "@$product"; # 'a1 a2 b1 b2'
    

返回的“发电机”是一个懒惰的绑扎数组,在询问它们时将生成值。还有迭代和其他访问者方法:

my $pairs = cartesian {@_} [qw/$ @ %/], ['a'..'z'], [1 .. 3];

while (my @tuple = $pairs->next) {  # $pairs->reset; #$pairs->index = 5; ...
    print @tuple, ', ';
}
# $a1, $a2, $a3, $b1, $b2, $b3, $c1, $c2, $c3, $d1, $d2, $d3, $e1 ...

我不知道您要使用的集合有多大,但是使用上述方法的优点是,生成器的存储要求仍然存在 O(1)

my $digits = cartesian {join '' => @_} ([0..9]) x 10;

say for @$digits[10**9 - 3 .. 10**9 + 3];

#   0999999998
#   0999999999
#   1000000000
#   1000000001
#   1000000002
#   1000000003

它仅计算了该集合的6个元素,并且什么也不存储。

从示例中可以看到,返回值 cartesian 本身是生成器对象,但是该对象的后续返回值是传递给 cartesian 返回。因此,如果您想要数组引用,它很简单: cartesian {\@_} ...


另外,您需要做些额外的工作来处理祝福参考?在任何意义上,除了什么 ref 将返回。如果您基于参考类型编写开关逻辑, Scalar::Util' reftype 是您应该使用的。

它祝福返回的阵列 cartesian 因此,当某些代码运行时

$b = $cartesian $a1, $a2;
$c = $cartesian $b, $a3;

...它可以检测到 $b 是先前调用模块的结果。

进行笛卡尔产品操作是微不足道的,如果该模块返回的数据不符合您的需求,请考虑从头开始操作。

无论如何,检查模块源代码表明它不是很好。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top