2012-06-12 47 views
2

我有一个大约有25000条记录的文件,每个记录有超过13个条目是药物名称。我想为这些条目形成所有可能的配对组合。例如:如果一条线有三条记录A,B,C,我应该组合成1)AB 2)AC 3)B C.下面是我从互联网上得到的代码,它只在一条线分配给数组:Perl形成字符串随机字符串组合

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"; 
} 

能否请你建议我解决这个问题呢?

+1

你的代码的标准是可怕的,我已经通过'perltidy'运行它,从而大大改善了它。对编程不熟悉并不适合马虎和不一致的布局。 – Borodin

回答

1

您正在将@n设置为包含@Drugs数组的第二个值的数组,请尝试在Math :: Combinatorics构造函数中使用data => \@Drugs

另外,使用严格;使用警告;等等等等等等。

+0

...并使用开放和词法文件句柄的三个参数版本......正确的缩进......不必要的使用'$ _' ...只需添加几个点。 – dgw

1

数组中的所有对都可以直接计算。根据您的问题使用药物A,B和C,您可能会认为它们形成方阵。

AA AB AC 
BA BB BC 
CA CB CC 

您可能不希望“对角线”对AA,BB和CC。请注意,其余元素是对称的。例如,元素(0,1)是AB,(1,0)是BA。再次,我认为这些是相同的,你不想重复。

要从线性代数中借用一个术语,您需要upper triangle。这样做可以消除施工中的重复,假定给定生产线上的每个药物名称都是唯一的。下面是一个算法。

  1. 依次选择每种药物q就行了。对于每一种,执行步骤2和3。
  2. 与药物开始立即q,然后对于每种药物- [R在列表的其余部分之后,执行步骤3。
  3. 记录对(q,r)。
  4. 录制的列表是所有唯一对的列表。

在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
0

我已经回答了这样的事情之前,为别人。对他们来说,他们对如何将一系列字母组合成所有可能的单词存在疑问。

看看How Can I Generate a List of Words from a group of Letters Using Perl。其中,您会看到一个使用my answerMath::Combinatoricsikegami具有的correct answer的示例。 (他用正则表达式做了一件很有趣的事情)。

我确信其中的一个会引导您找到您需要的答案。也许当我有更多的时间时,我会专门为你的问题提供一个答案。我希望这个链接有帮助。