私はあなたが参照するページ上のコードの非常に最初の部分を見ていた:私はそれを読みやすくするために少しそれを広げてきた
sub c{my$n=-1+shift;$n?map{my$c=$_;map$c.$_,c($n,@_)}@_:@_}
を。私はいくつかを含め
AA AB BA BB
AA AB BA BB
AAA AAB ABA ABB BAA BAB BBA BBB
AAA AAB ABA ABB BAA BAB BBA BBB
:両方のバージョンが同じように動作し、彼らはまったく同じ出力を生成
#!/usr/bin/perl
use strict;
use warnings;
sub c {
my $n=-1+shift;
$n ? map{
my $c = $_;
map $c . $_ , c($n ,@_)
} @_
: @_;
}
sub combinations {
my $number = shift; # remove the first item from @_
my @chars = @_; # the remainder of @_
$number --; # decrement $number, so that you will eventually exit
# from this recursive subroutine (once $number == 0)
if ($number) { # true as long as $number != 0 and $number not undef
my @result;
foreach my $char (@chars) {
my @intermediate_list = map { $char . $_ } combinations($number, @chars);
push @result, @intermediate_list;
}
return @result; # the current concatenation result will be used for creation of
# @intermediate_list in the 'subroutine instance' that called 'combinations'
}
else {
return @chars;
}
}
print join " ", combinations(2, "A", "B");
print "\n";
print join " ", c(2, "A", "B");
print "\n\n";
print join " ", combinations(3, "A", "B");
print "\n";
print join " ", c(3, "A", "B");
print "\n";
:また、私はそれをより明確にするために、それにいくつかの変更を(combinations
を参照してください)行いましたコード内のコメントですが、おそらく長めの説明が順番です!さて、物事の仕方を説明する例があります:「A」と「B」という2つのアイテムがあり、これらのアイテムのうち2つをすべて組み合わせたいとします。その場合、$number
は最初は2になり(ペアを取得したいので)、@chars
は('A', 'B')
に等しくなります。
初めてcombinations
が呼び出され、$number
は、このようにif
条件が満たされ、1に減らされ、我々はforeach
ループを入力しています。これは最初に$char
を 'A'に設定します。その後、combinations(1, ('A', 'B'))
を呼び出します。サブルーチンの呼び出し時に$number
が常に減るため、$number
はこの '子サブルーチン'で0になるため、結果として子は( 'A'、 'B')を返します。したがって:
@intermediate_list = map { $char . $_ } ('A', 'B'); # $char eq 'A'
map
次いで 'A' および 'B' の両方を受け取り、 'A'($ CHAR)と連結し、それぞれ、こうして( 'AA'、 'AB')です。 foreach
ループの次のラウンドでは、同じことが$char = B
で行われ、を( 'BA'、 'BB')に設定します。
各ラウンドでの内容が結果リストにプッシュされます。したがって、@result
に最終的にすべての可能な組み合わせが含まれます。
ペアの代わりにトリプレットを取得する場合は、明らかに$number = 3
で始まり、combinations
が3回呼び出されます。 2回目に呼び出されると、@result
、つまりペアを含むリストが返されます。そのリストの各項目は、最初の文字セットの各文字と連結されます。
これは意味があると思います。何かが明確になっていない場合はお尋ねください。
EDIT:下記のysthさんのコメントをご覧ください。
「3回呼び出されます」は「3の深さまで繰り返されます。実際には3つ以上のコールがあります(1つの文字がない限り...) – ysth
@ysthわかりました。以前は再帰的なサブルーチンを使ったことがありませんでした。したがって、この用語に精通していません。エラーを指摘してくれてありがとう! – canavanin