PHPで数学の「組合せ」をすべてリストアップするコードを書いてみました。
「組合せ」とは、n 個からm 個を選ぶ場合のすべてのパターンのことで、そのパターンの数は
=n!/(m!(m-n)!)
で表されます。
例えば、「1,2,3,4,5,6」という6個から4個を選ぶ場合には
1234、1235、1236、1245、1246、1256、1345、1346、1356、1456、2345、2346、2356、2456、3456
という15通りのパターンができます。
サンプル
下の関数「kumiawase」に、選ぶ元となる全体を配列で与え、また抜き取る数を与えると、すべてのパターンを配列で返します。
function kumiawase($zentai,$nukitorisu){
$zentaisu=count($zentai);
if($zentaisu<$nukitorisu){
return;
}elseif($nukitorisu==1){
for($i=0;$i<$zentaisu;$i++){
$arrs[$i]=array($zentai[$i]);
}
}elseif($nukitorisu>1){
$j=0;
for($i=0;$i<$zentaisu-$nukitorisu+1;$i++){
$ts=kumiawase(array_slice($zentai,$i+1),$nukitorisu-1);
foreach($ts as $t){
array_unshift($t,$zentai[$i]);
$arrs[$j]=$t;
$j++;
}
}
}
return $arrs;
}
$zentaisu=count($zentai);
if($zentaisu<$nukitorisu){
return;
}elseif($nukitorisu==1){
for($i=0;$i<$zentaisu;$i++){
$arrs[$i]=array($zentai[$i]);
}
}elseif($nukitorisu>1){
$j=0;
for($i=0;$i<$zentaisu-$nukitorisu+1;$i++){
$ts=kumiawase(array_slice($zentai,$i+1),$nukitorisu-1);
foreach($ts as $t){
array_unshift($t,$zentai[$i]);
$arrs[$j]=$t;
$j++;
}
}
}
return $arrs;
}
使用例
「1,2,3,4,5,6」という6個から4個を選ぶ場合の使用例を示します。
コメント
決まった配列内の数字を使ってn桁の全パターンの組合せを作るにはどうしたら良いでしょうか。
よろしくお願いいたします。
>匿名さん
具体的な場面が分かりませんが、上のサンプルが使えませんか。
$temps = kumiawase($arrs, $n);
$arrsは与えられた数字がセットされた配列、$nが取り出す桁数です。
しかし「n桁の全パターン」ということは組合せでなく順列のような気がしますがいかがでしょうか。
stabucky様ご返信ありがとうございます。
やりたい事は、10個の任意の数字を最大5つの組み合わせて、並び順の入れ替えも含め、その全てのパターンを出したいと考えております。
上のサンプルの場合、
1234、1235、1236、1245、1246、1256、1345、1346、1356、1456、2345、2346、2356、2456、3456の15パターンのみとなり、
2134、2135、2136…
などが省かれてしまっていたため、私が求めている組合せ全てというわではありませんでした。
さっそく順列について調べてみたいと思います。
>匿名さん
PHPでなくJavaScriptですが同じように配列と抜き取り数を与えて全ての順列を返すサンプルがありますので参考にしてください。
http://stabucky.com/wp/archives/5334
stabucky様ご返信ありがとうございます。
教えていただいたjsコードで何とか無事に思い通りの結果を出すことが出来ました。
この度は誠にありがとうございました。
>匿名さん
お役に立てたようで嬉しいです。