use Math::Combinatorics;
my @n = qw(a b c);
my $combinat = Math::Combinatorics->new(
count => 2,
data => [@n],
);
while ( my @combo = $combinat->next_combination ) {
print join( ' ', @combo ) . "\n";
}
我正在使用的代码,它不会产生任何输出:
open IN, "drugs.txt" or die "Cannot open the drug file";
open OUT, ">Combination.txt";
use Math::Combinatorics;
while (<IN>) {
chomp $_;
@Drugs = split /\t/, $_;
@n = $Drugs[1];
my $combinat = Math::Combinatorics->new(
count => 2,
data => [@n],
);
while ( my @combo = $combinat->next_combination ) {
print join( ' ', @combo ) . "\n";
}
print "\n";
}
你能否建议我解决这个问题?
答案 0 :(得分:1)
您将@n
设置为包含@Drugs
数组的第二个值的数组,尝试在Math :: Combinatorics构造函数中使用data => \@Drugs
。
另外,使用严格;使用警告; blahblahblah。
答案 1 :(得分:1)
数组中的所有对都可以直接计算。从您的问题中使用药物A,B和C,您可能会认为它们形成了一个方阵。
AA AB AC
BA BB BC
CA CB CC
您可能不希望“对角线”对AA,BB和CC。请注意,其余元素是对称的。例如,元素(0,1)是AB,(1,0)是BA。在这里,我再次假设它们是相同的,你不需要重复。
要从线性代数中借用一个术语,你需要upper triangle。这样做可以通过构造消除重复,假设给定线上的每个药物名称都是唯一的。对此的算法如下。
在Perl中,这看起来像
#! /usr/bin/env perl
use strict;
use warnings;
sub pairs {
my @a = @_;
my @pairs;
foreach my $i (0 .. $#a) {
foreach my $j ($i+1 .. $#a) {
push @pairs, [ @a[$i,$j] ];
}
}
wantarray ? @pairs : \@pairs;
}
my $line = "Perlix\tScalaris\tHashagra\tNextium";
for (pairs split /\t/, $line) {
print "@$_\n";
}
输出:
Perlix Scalaris Perlix Hashagra Perlix Nextium Scalaris Hashagra Scalaris Nextium Hashagra Nextium
答案 2 :(得分:0)
我之前已经为别人回答了这样的事情。对于他们来说,他们有一个关于如何将一系列字母组合成所有可能的单词的问题。
看看How Can I Generate a List of Words from a group of Letters Using Perl。在其中,您会看到使用Math::Combinatorics中的my answer和correct answer所拥有的ikegami的示例。 (他用正则表达式做了一些相当有趣的事情)。
我相信其中一项会引导您获得所需的答案。也许当我有更多时间时,我会专门针对你的问题充实答案。我希望这个链接有所帮助。