使用perl的未知2D阵列的所有可能的阵列组合

时间:2013-12-16 07:48:46

标签: arrays perl

我正在尝试为使用用户输入文件生成的2D数组生成所有可能的组合。我需要使用perl来获取它。 对于例如:

假设从输入文件形成的2D数组是这样的 -

[a, b, c]
[d, e]
[f, g]

此输入的预期输出如下 -

 [a, d, f] 
 [a, d, g] 
 [a, e, f] 
 [a, e, g] 
 [b, d, f] 
 [b, d, g] 
 [b, e, f] 
 [b, e, g]
 [c, d, f] 
 [c, d, g] 
 [c, e, f] 
 [c, e, g]

由于它是一个用户输入文件,行数和列数可以是任何东西,因此我无法使用固定数量的循环来创建此组合。

3 个答案:

答案 0 :(得分:1)

您需要cartesian product

使用CPAN模块,

use Set::CrossProduct;

my @arr = (
  [qw(a b c)],
  [qw(d e)],
  [qw(f g)],
);
my $iterator = Set::CrossProduct->new(\@arr);

use Data::Dumper;
print Dumper $iterator->combinations;

use strict;
use warnings;

my @arr = (
  [qw(a b c)],
  [qw(d e)],
  [qw(f g)],
);

local $" = ", ";
for my $aref ( getCartesian(@arr) ) {
  print "[@$aref]\n";
}

sub getCartesian {
#
  my @input = @_;
  my @ret = map [$_], @{ shift @input };

  for my $a2 (@input) {
    @ret = map {
      my $v = $_;
      map [@$v, $_], @$a2;
    }
    @ret;
  }
  return @ret;
}

输出

[a, d, f]
[a, d, g]
[a, e, f]
[a, e, g]
[b, d, f]
[b, d, g]
[b, e, f]
[b, e, g]
[c, d, f]
[c, d, g]
[c, e, f]
[c, e, g]

答案 1 :(得分:1)

这是另一种选择:

use strict;
use warnings;
use v5.14;

my @arr = ( [qw(a b c)], [qw(d e)], [qw(f g)] );

print "[$_]\n" for map s/-/, /gr, glob
    join '-', map { '{' . ( join ',', @$_ ) . '}' } @arr;

输出:

[a, d, f]
[a, d, g]
[a, e, f]
[a, e, g]
[b, d, f]
[b, d, g]
[b, e, f]
[b, e, g]
[c, d, f]
[c, d, g]
[c, e, f]
[c, e, g]

答案 2 :(得分:0)

这是一种看待它的方法。如果您已经获得了某些数字数组的结果,并且需要为其他数组添加这些结果,那么您可以执行以下操作:

sub get_combinations {
    my ($existing_results, $new_array) = @_;
    my $new_results;
    for my $existing_result (@$existing_results) { 
        for my $value (@$new_array) {
            push @$new_results, [ @$existing_result, $value ];
        }
    }
    return $new_results;
}

现在你可以简单地遍历你的2D数组:

my $inputs = [
    ['a', 'b', 'c'],
    ['d', 'e'],
    ['f', 'g'],
];
my $results = [ [] ];  # exactly one possible combination given no inputs
for my $input ( @$inputs ) {
    $results = get_combinations( $results, $input ); 
}
use Data::Dumper;
print Dumper $results;