第9講 プロシージャの再帰的使用
第4話 for文版順列作成の解説その1
お約束の通り、3次順列のおけるfor文版の解説を行います。
かなり難解だからです。
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
'変数の宣言と初期化
Dim h1, h2, s As Integer
Dim a(12) As Integer
s = 0
'データグリッドビューのデータのクリア
DataGridView1.Rows.Clear()
'順列の作成
For i = 1 To 3 '1番最初のセル
a(0) = i
For j = 1 To 3 '2番目のセル
a(1) = j
h1 = 1
If a(0) = a(1) Then h1 = 0 '1番目のセルと2番目のセルの重複検査
If h1 = 1 Then
For k = 1 To 3 '3番目のセル
a(2) = k
h2 = 1
For l = 0 To 1 '3番目のセルと1,2番目のセルの重複検査
If a(l) = a(2) Then
h2 = 0
Exit For
End If
Next
If h2 = 1 Then 'DataGridViewへの表示と総数カウント
DataGridView1.Rows.Add() '1行追加
For l = 0 To 2
DataGridView1(l, s).Value = a(l).ToString '順列の表示
Next
s = s + 1 '総数カウント
End If
Next
End If
Next
Next
DataGridView1.Rows.Add() '1行追加
DataGridView1(12, s + 1).Value() = s '総数の表示
End Sub
End Class
プログラムを読むときに、絶対欠かすことのできないことは、各変数の役割がなんなのかを理解することです。
各変数の枠割りを理解しないと、プログラミングコードは何度読んでもさっぱり意味のわからないものになります。
4次元ループになっているので、for文を制御する変数はi、j、k、lの4つです。
3次配列なのになぜ4次元なのでしょうか。
ここの理解が、次の自己再帰型を理解する際の要になります。
さて、i、j、kの役割は比較的はっきりしています。つまり、最初の3つの次元は比較的に理解が容易です。
0 | 1 | 2 |
最初の3つの次元は、セルの3に対応しています。
言い換えれば、3次配列の3に対応しています。
つまり、i、j、kはそれぞれセルに入る数字1,2,3に対応します。
各セルには1,2,3の数字が入ります。
1 | 2 | 3 |
1 | 3 | 2 |
2 | 1 | 3 |
2 | 3 | 1 |
3 | 1 | 2 |
3 | 2 | 1 |
つまり、色を対応させると
i、j、k |
となります。iは一番目のセルに入る数字1,2,3
jは2番目のセルに入る数字1,2,3
kは3番目のセルに入る数字1,2,3に対応しています。
では、lの役割はなんでしょうか。
実は、自己再帰型ではこれが枢要な役割を果たします。
(ただし、次話で示すコーティング例ではlはgの名称になっています。)
0 | 1 | 2 |
実は、lはセルの位置を示しています。
つまりセル番号を意味しています。
プログラミングを理解するときに、セル番号とセルに入る数字を明確に区別しなければなりません。
変数を理解するときに箱のラベルと箱の内容を区別しなければならなかったのと同じです。
ビール瓶でたとえれば、ラベルは『一番搾り』で内容は『ビール』です。
セル番号lは、箱のラベルに相当します。
入っている数字i、j、kは、箱の内容の相当します。
具体的には
では役割を明確にしたところで、トレースしてみましょう。
以下は、色を対応させながら見てください。
i=1のとき、
a(0) = i から0番目のセルに内容1が入ります。
セルの内容 | 1 | 2 | 3 |
セル番号 | 0 | 1 | 2 |
そして、
For j = 1 To 3 '2番目のセル
2次元目のループすなわちセル番号1の世界に入り、
a(1) = j から
セルの内容 | 1 | 1 | 3 |
セル番号 | 0 | 1 | 2 |
セル番号1のセルに内容1が入ります。次に、
h1 = 1
If a(0) = a(1) Then h1 = 0 '1番目のセルと2番目のセルの重複検査
の2行によって、h1=0となります。a(0)もa(1)も内容は1、1であるからです。
すると、
If h1 = 1 Then
For k = 1 To 3 '3番目のセル
a(2) = k
h2 = 1
For l = 0 To 1 '3番目のセルと1,2番目のセルの重複検査
If a(l) = a(2) Then
h2 = 0
Exit For
End If
Next
If h2 = 1 Then 'DataGridViewへの表示と総数カウント
DataGridView1.Rows.Add() '1行追加
For l = 0 To 2
DataGridView1(l, s).Value = a(l).ToString '順列の表示
Next
s = s + 1 '総数カウント
End If
Next
End If
の部分は実行されません。そして、2次元(jのループ)の2巡目に入り、a(1) = j から
セルの内容 | 1 | 2 | 3 |
セル番号 | 0 | 1 | 2 |
となります。そして、今回は
h1 = 1
If a(0) = a(1) Then h1 = 0 '1番目のセルと2番目のセルの重複検査
a(0)の内容は1、a(1)の内容は2で異なっていますので、
If文は実行されず、h1は書き換えられず1のままですから、
If h1 = 1 Then
For k = 1 To 3 '3番目のセル
a(2) = k
h2 = 1
For l = 0 To 1 '3番目のセルと1,2番目のセルの重複検査
If a(l) = a(2) Then
h2 = 0
Exit For
End If
Next
If h2 = 1 Then 'DataGridViewへの表示と総数カウント
DataGridView1.Rows.Add() '1行追加
For l = 0 To 2
DataGridView1(l, s).Value = a(l).ToString '順列の表示
Next
s = s + 1 '総数カウント
End If
Next
End If
が実行されます。
For k = 1 To 3 '3番目のセル
で3次元目のループ=セル番号2の世界=kのループ に入ります。
a(2) = k によって、
セルの内容 | 1 | 2 | 1 |
セル番号 | 0 | 1 | 2 |
となります。
For l = 0 To 1 '3番目のセルと1,2番目のセルの重複検査
If a(l) = a(2) Then
h2 = 0
Exit For
End If
Next
の1巡目のループにおいて、1と1が比較され内容が同じなので、
if(a[l]==a[2]){
h2=0;
break;
}
によって、h2は0となり、for文も強制的に終了となります。
3次元目の2回目のループのa[2]=k;によって、
セルの内容 | 1 | 2 | 2 |
セル番号 | 0 | 1 | 2 |
となります。そして、
If a(l) = a(2) Then
h2 = 0
Exit For
End If
の1巡目のループによって、1と2が比較されますが、今度は内容が違うのでIf文はスルーされます。
ところが、2巡目のループによって2と2が比較され内容が同じなので、If文が実行されてしまいh2は0となってしまいます。すると、
If h2 = 1 Then 'DataGridViewへの表示と総数カウント
DataGridView1.Rows.Add() '1行追加
For l = 0 To 2
DataGridView1(l, s).Value = a(l).ToString '順列の表示
Next
s = s + 1 '総数カウント
End If
は実行されず、3次元目ループの3巡目に入り、a(2) = k によって、
セルの内容 | 1 | 2 | 3 |
セル番号 | 0 | 1 | 2 |
となります。3巡目においては、
For l = 0 To 1 '3番目のセルと1,2番目のセルの重複検査
If a(l) = a(2) Then
h2 = 0
Exit For
End If
Next
は1回目において1と3が、2回目において2と3が比較されますが、いずれも内容が違うのでIf文は一度も実行されずに終わりますので、
h2は1のままで、
If h2 = 1 Then 'DataGridViewへの表示と総数カウント
DataGridView1.Rows.Add() '1行追加
For l = 0 To 2
DataGridView1(l, s).Value = a(l).ToString '順列の表示
Next
s = s + 1 '総数カウント
End If
が実行され、1個目の順列がデータグリッドビューに表示され、s = s + 1 によって、順列の個数が1とカウントされます。
変数sの役割は、順列総数のカウントだったわけです。
かなり、長くなったので以降のトレースは次話で。
VC++講義第1部へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
数学研究室に戻る