FC2ブログ
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

# 重複組合せの組合せ生成 Repetition Combination Combination Generator
# 引数 N個 R個 値 (\@N, \@R, \@Value)
# 戻り値 重複組合せの組合せ生成 (@RepetitionCombinationCombination)
sub REPETITIONCOMBINATIONCOMBINATION{
my ($N, $R, $Value) = @_;
my @RepetitionCombinationCombination = ();
my @TempRepetitionCombinationCombination = ();
my @RepetitionCombinationGenerator = ();
my @Position = ();
my $PossibleToMove = 0;
my $CurrentPosition = 0;
my $RepetitionCombinationCombinationPosition = 0;
my $Count = @$Value;
my $Count1 = $Count - 1;

# 個数と配列数の確認
for(my $i = 0; $i < $Count; $i++){
if(($$N[$i] <= 0) || ($$R[$i] <= 0) || ($$N[$i] < $$R[$i]) || ($$N[$i] > @{$$Value[$i]})){
return 0;
}
}

# 重複組合せ生成の取得
for(my $i = 0; $i < $Count; $i++){
@{$RepetitionCombinationGenerator[$i]} = &REPETITIONCOMBINATIONGENERATOR($$N[$i], $$R[$i], $$Value[$i]);
}

for(my $i = 0; $i < $Count; $i++){
# 初期化 Initialization
&Initialization($Count, \@Position);
$Position[0] = $i;

# 重複組合せ生成の値
$TempRepetitionCombinationCombination[0] = $RepetitionCombinationGenerator[$CurrentPosition][$Position[$CurrentPosition]];

# 重複組合せ生成の位置
$CurrentPosition++;

while($CurrentPosition > 0){
# 移動可能 Possible to Move
$PossibleToMove = (($Position[$CurrentPosition] + 1) < @{$RepetitionCombinationGenerator[$CurrentPosition]} ? ($Position[$CurrentPosition] + 1) : -1);

if($PossibleToMove != -1){
# 配列の位置
$Position[$CurrentPosition] = $PossibleToMove;
# 重複組合せ生成の値
$TempRepetitionCombinationCombination[$CurrentPosition] = $RepetitionCombinationGenerator[$CurrentPosition][$Position[$CurrentPosition]];

if($CurrentPosition == $Count1){
# 重複組合せの組合せ生成 Combination Combination Generator
$RepetitionCombinationCombination[$RepetitionCombinationCombinationPosition] = join(" ", @TempRepetitionCombinationCombination);

# 重複組合せの組合せ生成 配列の位置
$RepetitionCombinationCombinationPosition++;
}else {
# 重複組合せ生成の位置
$CurrentPosition++;
}
}else {
# 配列情報を削除 Delete Position
$Position[$CurrentPosition] = -1;

# 配列の位置
$CurrentPosition--;
}
}
}

return @RepetitionCombinationCombination;
}

# 重複組合せ生成 Repetition Combination Generator
# 引数 N個 R個 値 ($N, $R, \@Value)
# 戻り値 重複組合せ生成 (@RepetitionCombination)
sub REPETITIONCOMBINATIONGENERATOR{
my ($N, $R, $Value) = @_;
my @RepetitionCombination = ();
my @TempRepetitionCombination = ();
my @Position = ();
my $PossibleToMove = 0;
my $CurrentPosition = 0;
my $RepetitionCombinationPosition = 0;
$N = int($N);
$R = int($R);
my $R1 = $R - 1;
my $Count = @$Value;

# 個数と配列数の確認
if(($N <= 0) || ($R <= 0) || ($N < $R) || ($N > $Count)){
return 0;
}

if($R == 1){
return @$Value;
}

# 初期化 Initialization
for(my $i = 0; $i < $R; $i++){
$Position[$i] = -1;
}

for(my $i = 0; $i < $N; $i++){
# 現在位置
$Position[0] = $i;

# 順列の値
$TempRepetitionCombination[0] = $$Value[$i];

# 配列の位置
$CurrentPosition++;

while($CurrentPosition > 0){
# 移動可能 Possible to Move
$PossibleToMove = &PossibleToMove($N, $CurrentPosition, \@Position);

if($PossibleToMove != -1){
# 配列の位置
$Position[$CurrentPosition] = $PossibleToMove;
# 順列の値
$TempRepetitionCombination[$CurrentPosition] = $$Value[$Position[$CurrentPosition]];

if($CurrentPosition == $R1){
# 重複組合せ生成 Repetition Combination Generator
$RepetitionCombination[$RepetitionCombinationPosition] = join(" ", @TempRepetitionCombination);

# 重複組合せ生成 配列の位置
$RepetitionCombinationPosition++;
}else {
# 配列の位置
$CurrentPosition++;
}
}else {
# 配列情報を削除 Delete Position
$Position[$CurrentPosition] = -1;

# 配列の位置
$CurrentPosition--;
}
}
}

return @RepetitionCombination;
}

# 初期化 Initialization
# 引数 R個 現在の位置 ($R, \@Position)
# 戻り値 なし ()
sub Initialization{
my ($R, $Position) = @_;

# 配列の位置
for(my $i = 0; $i < $R; $i++){
$$Position[$i] = -1;
}
}

# 移動可能 Possible to Move
# 引数 N個 配列の位置 使用できない位置 ($N, $CurrentPosition, \@Position)
# 戻り値 移動可能な位置 ($PossibleToMove)
sub PossibleToMove{
my ($N, $CurrentPosition, $Position) = @_;
my $PossibleToMove = -1;

if(($$Position[$CurrentPosition] + 1) < $N){
if($$Position[$CurrentPosition] < $$Position[$CurrentPosition - 1]){
$PossibleToMove = $$Position[$CurrentPosition - 1];
}else {
$PossibleToMove = $$Position[$CurrentPosition] + 1;
}
}

return $PossibleToMove;
}




use warnings;
use strict;

my @N = (3, 4, 7);
my @R = (1, 2, 3);
my @Value = ([1,2,3],["a","b","c","d"],[1,2,3,4,5,6,7]);
my @RepetitionCombinationCombination = &REPETITIONCOMBINATIONCOMBINATION(\@N, \@R, \@Value);
foreach(@RepetitionCombinationCombination){
print "$_\n";
}


参考URL
perlで順列・組合せ 6 重複組合せ生成 (Repetition Combination Generator: REPETITIONCOMBINATIONGENERATOR): perlで順列・組合せ:一寸先は闇
オンライン コンパイラ/インタプリタ
テクニカル分析
プロフィール

Author:雨宮
Firefoxを使用しているので気づかなかったけど、IE6でソースコードを上手くコピーできない

5/3
携帯用ならIE6でもソースコードをコピーできる
携帯用

検索フォーム


あわせて読みたいブログパーツ
一寸先は闇 RSS

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。