在Perl中,如何在所有非对角元素之前输出集合的笛卡尔积的对角线?

时间:2014-05-14 13:58:24

标签: perl

我想输出两个字母的所有组合,但我希望首先显示相同字母之间的组合。基本上,我想得到这样的东西:

如果我有

@list = ("A", "B", "C")

我希望我的输出为:

AA  -
BB  -
CC  -
AB
AC
BA
BC
CA
CB

通常情况下,如果我只使用两个for循环我就会

AA  -
AB
AC
BA
BB  -
BC
CA
CB
CC  -

是否有任何快速(易于理解/简单)的方式来获得我想要的输出?

4 个答案:

答案 0 :(得分:3)

这已经得到了解决,但我认为最简单的解决方案就是在自定义代码中处理您的特殊情况,然后依靠标准模块来完成其他任务。

对于组合模块,可以使用Algorithm::CombinatoricsMath::Combinatorics

use strict;
use warnings;

use Algorithm::Combinatorics qw(variations_with_repetition);
use List::MoreUtils qw(uniq);

my @set = ('A'..'C');
my $length = 3;

# Trivial Diagonal Solutions
for my $element (@set) {
    my @solution = ($element) x $length;
    print "@solution\n"
}

# All Other Solutions
my $iter = variations_with_repetition(\@set, $length);
while (my $p = $iter->next) {
    next if 1 == uniq @$p;
    print "@$p\n"
}

答案 1 :(得分:1)

我无法想到比以下更简单的方法:

@letters = ( 'A', 'B' );
@list = ( $letters[0].$letters[0], $letters[1].$letters[1], $letters[0].$letters[1], $letters[1].$letters[0] );

答案 2 :(得分:1)

for (glob("{A,B,C}{A,B,C}")) {
  print;
  print " -" if /(.)\1/;
  print "\n";
}

答案 3 :(得分:0)

for my $e (@list) {
    say $e.$e;
}

for my $i (0..$#list) {
    for my $j (0..$#list) {
        say $list[$i].$list[$j] if $i != $j;
    }
}

它应该符合您的要求,因为它比之前提出的解决方案 [1] 快3倍,但它仍然非常清楚。


  1. 另一个答案中有一个基准,但它被删除了。