|
ゆか さん、皆さん、こんばんは。
>エクセル初心者です。
>例えば、A、B、C、D 4つのアルファベットを、二組に分けたものの組み合わせを全て表示させるようなプログラムを作りたいのですが、探してもアイデアが見つかりません。
>どなたかわかる方教えてください。
この問題は、組合せリストを作成するアルゴリズムがネックですよね!!
例えば、例題のようにメンバがA、B、C、Dの場合だと
A組 : B組のメンバ数が
1 : 3
2 : 2
という組合せがあります。
1:3の場合は、Combin(4,1)=4の組合せ数になりますが、
2:2の場合は、Combin(4,2)/2=3の組合せ数になりますよね?
(Combinについては、ワークシート関数を参照して下さい)
基本的には、総リストから1を選ぶ組合せ、2つを選ぶ組合せのリストを作成し、
残ったメンバがもう一組のメンバと言う事になりますが、
既に投稿されいるように
1:3の場合は、4つから1つを選ぶ組合せリストを作成すると
残り
A BCD
B ACD
C ABD
D ABC
でも、2:2の場合は、4つから2つを選ぶ組合せリストを作成すると
4つから2つを選ぶ組合せリストを作成すると
残り
1 AB CD
2 AC BD
3 AD BC
4 BC AD
5 BD AC
6 CD AB
とダブりが生じるのでここの工夫が必要ですが、これは帰納的な発想をすると、
上記の1(AB)と6(CD)、2と5、3と4 という組を形成できます。
「アイデア」とあったので、全部のコードは載せませんが、
組合せだけ・・・・。
実は、組合せはここのサイトで以前にも質問がありまして、
http://www.vbalab.net/vbaqa/c-board.cgi?cmd=one;no=16249;id=excel
こんな方法でも可能だし、場合によっては、これの方が都合の良い事も有るのですが、
私の勉強も兼ねて別解で作りました。
'============================
Sub test()
Dim 組合せ
組合せ = combin_list(Array("a", "b", "c", "d"), 2)
Range(Cells(1, 1), Cells(UBound(組合せ, 1) - LBound(組合せ, 1) + 1, 2)).Value = 組合せ
End Sub
'========================================
Function combin_list(総リスト, 抜取り数, Optional ByVal nest As Long = 0, Optional ByVal st As Long = 0)
'組合せリストを作成する
'input :総リスト----組合せリストを作成する元リスト(1次元の配列)
' 抜取り数----組合せ抜取り数
' nest及び、stは、指定不可 内部で使用するパラメータ
'output:combin_list---組合せリスト2次元配列
Static ans()
Static idx() As Long
Static jdx As Long
If nest = 0 Then
jdx = 0
ReDim idx(抜取り数 - 1)
ReDim ans(WorksheetFunction.Combin(UBound(総リスト) - LBound(総リスト) + 1, 抜取り数) - 1, 抜取り数 - 1)
st = LBound(総リスト)
End If
For idx(nest) = st To UBound(総リスト)
If nest < 抜取り数 - 1 Then
Call combin_list(総リスト, 抜取り数, nest + 1, idx(nest) + 1)
Else
For kdx = 0 To 抜取り数 - 1
ans(jdx, kdx) = 総リスト(idx(kdx))
Next kdx
jdx = jdx + 1
End If
Next
If nest = 0 Then
combin_list = ans()
End If
End Function
これでnCrの組合せリストの作成は可能です。
後は、呼び出し元で、抜取り数が1のとき、2のときの残りのメンバを作成する方法
を上記を参考にして考えてみて下さい。
|
|