2012-04-24 10 views
16

私はリストを持つファイルを持っており、各行を比較するファイルを作る必要があります。私はこのように見えるように最終的なリストをご希望のPerlでは、リストのすべての組み合わせをどのように生成できますか?

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でこれを実行しようとしていると持っています例えば、私のファイルはこれを持っています少しのトラブル。私は配列を作って分割する必要があることを知っていますが、その後は何か問題があります。

+0

あなたのこれまでのコードを投稿してください。 – tuxuday

答えて

0
    1. は、元の文字列に
  1. を次の文字列を取り付ける終了する次の位置からアレイ上
  2. 反復は、次の文字列を取り、2
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 
+3

質問のサンプルデータを使ってみませんか? – daxim

+1

@ daxim:IntensionはOPのためにいくつかの仕事を残しました。 –

0

方法について:

#!/usr/bin/perl 
use strict; 
use warnings; 
use Data::Dump qw(dump); 

my @in = qw(AAA BBB CCC DDD EEE); 
my @list; 
while(my $first = shift @in) { 
    last unless @in; 
    my $rest = join',',@in; 
    push @list, glob("{$first}{$rest}"); 
} 
dump @list; 

出力:

(
    "AAABBB", 
    "AAACCC", 
    "AAADDD", 
    "AAAEEE", 
    "BBBCCC", 
    "BBBDDD", 
    "BBBEEE", 
    "CCCDDD", 
    "CCCEEE", 
    "DDDEEE", 
) 
+5

グロブ・トリックには、いつ障害が発生したかに関するさまざまな警告が付いていなければなりません。 – daxim

+1

@daxim:現在の作業ディレクトリにあるファイルの "副作用"を意味しますか?もしそうなら、 '?'、 '[]'や '*'を使わないので完全に安全ではないでしょうか? – flesk

+1

そのすべて。私は今、悩まされています。注意点は、明確に表示されるべきであり、レトリックの質問は視認性の低いコメントではありません。それは「副作用」ではなく、実際に起こります。言葉を改変するのは間違っています。それは安全ではありません。明らかに、ユーザーは質問に作成/匿名化されたデータを提供し、現実の状況下では驚くべきことになります。 SOの回答は、失敗のために人を設定しないように努めなければならない、彼らは常に微妙さとリスクを認識する必要があります。私はM42にそれを改善するインセンティブを与えるために、この答えを下降させました。 - 継続: – daxim

28

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

出力:

my @list = qw(AAA BBB CCC DDD EEE); 

for my $i (0..$#list-1) { 
    print join "\n", glob sprintf "{'$list[$i] '}{%s}", 
      join ",", @list[$i+1..$#list]; 
    print "\n"; 
} 

出力:

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

P.S.

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

ここglobを使用してハックです現在の作業ディレクトリで一致するファイルの警告を避けるには、Text::Glob::ExpandまたはString::Glob::Permuteモジュールを平文​​3210の代わりに使用することをお勧めします。

+4

globトリックには、いつ障害が発生したかに関するさまざまな注意事項が付随していなければなりません。 – daxim

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

編集

私の謝罪 - 私の代わりに組み合わせの順列を生成していました。

このコードは正しいです。

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

出力

AAA BBB 
AAA CCC 
AAA DDD 
AAA EEE 
BBB CCC 
BBB DDD 
BBB EEE 
CCC DDD 
CCC EEE 
DDD EEE 
関連する問題