在Perl中,如何生成列表的所有可能组合?

use*_*084 16 arrays perl combinations combinatorics

我有一个带有列表的文件,需要创建一个文件,将每行与另一行进行比较.例如,我的文件有这个:

AAA  
BBB  
CCC  
DDD  
EEE

我希望最终列表看起来像这样:

AAA  BBB  
AAA  CCC  
AAA  DDD  
AAA  EEE  
BBB  CCC  
BBB  DDD  
BBB  EEE  
CCC  DDD  
CCC  EEE  
DDD  EEE

我试图在Perl中这样做,这是第一次,我遇到了一些麻烦.我知道你需要制作一个数组,然后拆分它,但之后我遇到了一些麻烦.

Sin*_*nür 29

使用Algorithm :: Combinatorics.基于迭代器的方法比一次生成所有内容更可取.

#!/usr/bin/env perl

use strict; use warnings;
use Algorithm::Combinatorics qw(combinations);

my $strings = [qw(AAA BBB CCC DDD EEE)];

my $iter = combinations($strings, 2);

while (my $c = $iter->next) {
    print "@$c\n";
}
Run Code Online (Sandbox Code Playgroud)

输出:

AAA BBB
AAA CCC
AAA DDD
AAA EEE
BBB CCC
BBB DDD
BBB EEE
CCC DDD
CCC EEE
DDD EEE


Bor*_*din 8

使用递归来编写它是很简单的.

此代码示例演示.

use strict;
use warnings;

my $strings = [qw(AAA BBB CCC DDD EEE)];

sub combine;

print "@$_\n" for combine $strings, 5;

sub combine {

  my ($list, $n) = @_;
  die "Insufficient list members" if $n > @$list;

  return map [$_], @$list if $n <= 1;

  my @comb;

  for my $i (0 .. $#$list) {
    my @rest = @$list;
    my $val  = splice @rest, $i, 1;
    push @comb, [$val, @$_] for combine \@rest, $n-1;
  }

  return @comb;
}
Run Code Online (Sandbox Code Playgroud)

编辑

我道歉 - 我正在产生排列而不是组合.

这段代码是正确的.

use strict;
use warnings;

my $strings = [qw(AAA BBB CCC DDD EEE)];

sub combine;

print "@$_\n" for combine $strings, 2;

sub combine {

  my ($list, $n) = @_;
  die "Insufficient list members" if $n > @$list;

  return map [$_], @$list if $n <= 1;

  my @comb;

  for (my $i = 0; $i+$n <= @$list; ++$i) {
    my $val  = $list->[$i];
    my @rest = @$list[$i+1..$#$list];
    push @comb, [$val, @$_] for combine \@rest, $n-1;
  }

  return @comb;
}
Run Code Online (Sandbox Code Playgroud)

产量

AAA BBB
AAA CCC
AAA DDD
AAA EEE
BBB CCC
BBB DDD
BBB EEE
CCC DDD
CCC EEE
DDD EEE
Run Code Online (Sandbox Code Playgroud)


Nik*_*ain 7

看一下Math :: Combinatorics - 在列表上执行组合和排列

示例从CPAN复制:

use Math::Combinatorics;

  my @n = qw(a b c);
  my $combinat = Math::Combinatorics->new(count => 2,
                                          data => [@n],
                                         );

  print "combinations of 2 from: ".join(" ",@n)."\n";
  print "------------------------".("--" x scalar(@n))."\n";
  while(my @combo = $combinat->next_combination){
    print join(' ', @combo)."\n";
  }

  print "\n";

  print "permutations of 3 from: ".join(" ",@n)."\n";
  print "------------------------".("--" x scalar(@n))."\n";
  while(my @permu = $combinat->next_permutation){
    print join(' ', @permu)."\n";
  }

  output:
combinations of 2 from: a b c
  ------------------------------
  a b
  a c
  b c

  permutations of 3 from: a b c
  ------------------------------
  a b c
  a c b
  b a c
  b c a
  c a b
  c b a
Run Code Online (Sandbox Code Playgroud)

  • 为什么不使用问题中的示例数据? (3认同)

msa*_*sam 0

  1. 取第一个字符串
  2. 从下一个位置到末尾迭代数组
    1. 将下一个字符串附加到原始字符串
  3. 获取下一个字符串并返回步骤 2