第11講 Subプロシージャの再帰的使用の学習

第7話 Subプロシージャ版順列作成の解説その4

Dim a(15) As Byte
Dim cn As Long
Dim n As Byte
Private Sub CommandButton1_Click()
  n = Cells(2, 10)
  cn = 0
  f (0)
  Cells(3, 13) = cn
End Sub

Sub f(g As Integer)
  Dim i As Byte, j As Byte, h As Byte
  For i = 1 To n
    a(g) = i
    h = 1
    If g > 0 Then
      For j = 0 To g - 1
        If a(g) = a(j) Then
          h = 0
          Exit For
        End If
      Next
    End If
    If h = 1 Then
      If
g + 1 < n Then
        
f (g + 1)
      Else
        For j = 0 To n - 1
          Cells(5 + 2 * Int(cn / 10), 1 + (n + 1) * (cn Mod 10) + j) = a(j)
        Next
        cn = cn + 1
      End If
    End If
  Next

End Sub

2 1 3

これでf (2)の3回目の生は終わりを告げ、消滅しf (1)へと戻ります。

2 1

そして、Nextにより

2 2

となりますが、これは
    h = 1
    If g > 0 Then
      For j = 0 To g - 1
        If a(g) = a(j) Then
          h = 0
          Exit For
        End If
      Next
    End If
によってチェックされてしまい、
    If h = 1 Then
      If
g + 1 < n Then
        
f (g + 1)
      Else
        For j = 0 To n - 1
          Cells(5 + 2 * Int(cn / 10), 1 + (n + 1) * (cn Mod 10) + j) = a(j)
        Next
        cn = cn + 1
      End If
    End If
無視されますから、Nextにより

2 3

今回は
    h = 1
    If g > 0 Then
      For j = 0 To g - 1
        If a(g) = a(j) Then
          h = 0
          Exit For
        End If
      Next
    End If
の試験に合格して
    If h = 1 Then
      If
g + 1 < n Then
        
f (g + 1)
      Else
        For j = 0 To n - 1
          Cells(5 + 2 * Int(cn / 10), 1 + (n + 1) * (cn Mod 10) + j) = a(j)
        Next
        cn = cn + 1
      End If
    End If
命令が実施され、f (
2)の4回目の発生となります。

2 3

  For i = 1 To n
    a(g) = i
によって

2 3 1

3つともセルの内容が違いますので、
試験
    h = 1
    If g > 0 Then
      For j = 0 To g - 1
        If a(g) = a(j) Then
          h = 0
          Exit For
        End If
      Next
    End If
はあっさりクリアして
    If h = 1 Then
      If g + 1 < n Then
        f (g + 1)
      Else
        For j = 0 To n - 1
          Cells(5 + 2 * Int(cn / 10), 1 + (n + 1) * (cn Mod 10) + j) = a(j)
        Next
        cn = cn + 1
      End If
    End If
の否定側の
      Else
        For j = 0 To n - 1
          Cells(5 + 2 * Int(cn / 10), 1 + (n + 1) * (cn Mod 10) + j) = a(j)
        Next
        cn = cn + 1
      End If
の命令が遂行され、4個目の順列4個目の順列をシートにはき出します。
Nextにより、

2 3 2

となりますが、これは1番目のセルと3番目のセルが同じなので、検査
    h = 1
    If g > 0 Then
      For j = 0 To g - 1
        If a(g) = a(j) Then
          h = 0
          Exit For
        End If
      Next
    End If
に抵触して、

2 3 3

となります。今度は、2番目のセルと3番目のセルの内容が同じなので、やはり
    h = 1
    If g > 0 Then
      For j = 0 To g - 1
        If a(g) = a(j) Then
          h = 0
          Exit For
        End If
      Next
    End If
の試験をクリアできません。
これで、f (
2)の4回目の生が寿命を迎え、消滅します。

2 3

そして、セル番号1の世界も天寿を全うし、2度目の消滅を体験します。

2

Nextにより

3

となり、g=0なので試験
    If g > 0 Then
      For j = 0 To g - 1
        If a(g) = a(j) Then
          h = 0
          Exit For
        End If
      Next
    End If
スルーされ、
    If h = 1 Then
      If g + 1 < n Then
        f (g + 1)
      Else
        For j = 0 To n - 1
          Cells(5 + 2 * Int(cn / 10), 1 + (n + 1) * (cn Mod 10) + j) = a(j)
        Next
        cn = cn + 1
      End If
    End If
の肯定側
      If g + 1 < n Then
        f (g + 1)
実行されf (1)の3度目の誕生を迎えます。

3

  For i = 1 To n
    a(g) = i
によって、

3 1

これは、2つのセルに内容が違いますので、
    If h = 1 Then
      If g + 1 < n Then
        f (g + 1)
      Else
        For j = 0 To n - 1
          Cells(5 + 2 * Int(cn / 10), 1 + (n + 1) * (cn Mod 10) + j) = a(j)
        Next
        cn = cn + 1
      End If
    End If
の肯定部分が遂行され、f (2)の5度目の生誕となります。

3 1 i

For文によって

3 1 1


3 1 2

と変化していって、はじめて3つのセルの内容がすべて異なり、
    If h = 1 Then
      If g + 1 < n Then
        f (g + 1)
      Else
        For j = 0 To n - 1
          Cells(5 + 2 * Int(cn / 10), 1 + (n + 1) * (cn Mod 10) + j) = a(j)
        Next
        cn = cn + 1
      End If
    End If
の否定部分の命令が遂行され5個目の順列5個目の順列がシートに出力されます。
以下、

3 1 3

セル番号の世界の5度目の消滅。

3 1


3 2


3 2 1

と変化していき、6個目の順列6個目の順列がシートに打ち出されます。

3 2 2


3 2 3

セル番号の世界の6度目の消滅。

3 2


3 3

セル番号の世界の3度目の消滅。

3

セル番号0の世界のはじめての消滅を迎え、プログラムは
f (0)を呼び出してからはじめてPrivate Sub CommandButton1_Clickに戻り、
最後の命令Cells(3, 13) = cnを遂行して、自分の任務をすべて完遂し終焉を迎えます。
プログラムは、消滅しましたが、シートには結果燦然と輝く結果
が燦然と輝いています。

最後の方、叙述を簡単にしましたが、簡略にした部分を皆さんが補ってください。
詳しい記述を延々と繰り返したのでは、逆に読む気力が失せると考え、簡単にしました。

n=3を選んだ理由はお分かりですね。n=2ではトレースとして簡単すぎます。
しかし、n=4では、私も書く気になれませんし、読む皆さんもウンザリですよね。

みなさん、n=4のトレースは大変ですが、頭の中でやってみてください。
コンピュータの動きを追うことはとても大切なことです。

では、皆さんわかりやすさを優先して、Dim a(15) As Integer Dim cn As Long Dim cn As Longをグローバルとして
引数1つのプロシージャSub f(g As Integer)としましたが、
グローバル配列とグローバル変数をやめて、プロシージャもSub f(g As Integer,cn As Long,n As Byte,a() As Byte)と引数を4つにするプログラムを考えてください。
尚、a() As Byteのようにすれば配列も引数として引き渡すことが出来ます。



第6話へ 第8話へ

004
  


VBA講義第1部へ
vc++講義へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座へ
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座へ

数学研究室に戻る