第2話 再帰的呼び出し型のメリット
メリットは次の2つを見れば一目瞭然です。
7次順列をループ文で作った場合と
再帰的呼び出しで作った場合です。
7次順列ループ方式
7次順列再帰的呼び出し方式


7次順列ループ方式のプログラムソース
Private Sub CommandButton1_Click()

  Dim i As Integer, j As Integer, k As Integer, l As Integer, h1 As Integer, h2 As Integer, h3 As Integer, h4 As Integer, h5 As Integer, h6 As Integer, jyn(7) As Integer
  Dim sousuu As Long

  sousuu = 0
  For i = 1 To 7
    jyn(1) = i
    For j = 1 To 7
      jyn(2) = j
      h1 = 1
      For k = 1 To 1
        If jyn(2) = jyn(k) Then
          h1 = 0
          Exit For
        End If
      Next
      If h1 = 1 Then
        For k = 1 To 7
          jyn(3) = k
          h2 = 1
          For l = 1 To 2
            If jyn(3) = jyn(l) Then
              h2 = 0
              Exit For
            End If
          Next
          If h2 = 1 Then
            For l = 1 To 7
              jyn(4) = l
              h3 = 1
              For m = 1 To 3
                 If jyn(4) = jyn(m) Then
                  h3 = 0
                  Exit For
                End If
                Next
                If h3 = 1 Then
                  For m = 1 To 7
                    jyn(5) = m
                    h4 = 1
                    For n = 1 To 4
                      If jyn(5) = jyn(n) Then
                        h4 = 0
                        Exit For
                      End If
                    Next
                    If h4 = 1 Then
                      For n = 1 To 7
                        jyn(6) = n
                        h5 = 1
                        For o = 1 To 5
                          If jyn(6) = jyn(o) Then
                            h5 = 0
                            Exit For 
                          End If
                        Next
                        If h5 = 1 Then
                          For o = 1 To 7
                          jyn(7) = o
                          h6 = 1
                          For p = 1 To 6
                            If jyn(7) = jyn(p) Then
                                h6 = 0
                                Exit For
                              End If
                            Next
                            If h6 = 1 Then

                            sousuua = sousuu Mod 8
                            sousuus = Int(sousuu / 8)
                            sousuu = sousuu + 1

                            For p = 1 To 7
                              Cells(5 + sousuus * 2, 1 + p + sousuua * 8) = jyn(p)
                            Next
                          End If
                        Next
                      End If
                    Next
                  End If
                Next
              End If
            Next
          End If
        Next
      End If
    Next
  Next

End Sub

7次元ループになっていて、
同じような記述が永遠と繰り返されています。
繰り返しはコンピュータの得意技であって、
人間がやるべきではありません。
ところが、再帰的呼び出しにすると、

Dim jyn(7) As Integer
Dim sousuu As Long
Private Sub CommandButton1_Click()

  sousuu = 0
  jyunretusakusei (1)

End Sub

Sub jyunretusakusei(g As Integer)

  Dim i As Integer, j As Integer, h As Integer

  For i = 1 To
7
    jyn(g) = i
    h = 1
    If g > 1 Then
      For j = 1 To g - 1
        If jyn(g) = jyn(j) Then
          h = 0
          Exit For
        End If
      Next
    End If
    If h = 1 Then
      If g <
7 Then
        jyunretusakusei (g + 1)
      Else
        sousuua = sousuu Mod 8
        sousuus = Int(sousuu / 8)
        sousuu = sousuu + 1

        For j = 1 To
7
          Cells(5 + sousuus * 2, 1 + j + sousuua *
8) = jyn(j)
        Next
      End If
    End If
  Next

End Sub

とシンプルになっています。さらに、注目点は3次の場合との比較です。
Dim jyn(3) As Integer
Dim sousuu As Long

Private Sub CommandButton1_Click()

  sousuu = 0
  jyunretusakusei (1)

End Sub

Sub jyunretusakusei(g As Integer)

  Dim i As Integer, j As Integer, h As Integer

  For i = 1 To 3
    jyn(g) = i
    h = 1
    If g > 1 Then
      For j = 1 To g - 1
        If jyn(g) = jyn(j) Then
          h = 0
          Exit For
        End If
      Next
    End If
    If h = 1 Then
      If g < 3 Then
        jyunretusakusei (g + 1)
      Else 
        sousuua = sousuu Mod 8
        sousuus = Int(sousuu / 8)
        sousuu = sousuu + 1

        For j = 1 To 3
          Cells(5 + sousuus * 2, 1 + j + sousuua * 4) = jyn(j)
        Next
      End If
    End If
  Next

End Sub

要するに3次の場合の3を(4は3+1、8は+1と考えてください。)に変更するでだけでよいのです。
7次でさえこれだけ違います。
これが20次ぐらいになったら再帰的呼び出しが如何に便利かわかるでしょう。

プログラムはまだ改良の余地があります。
3や7を例えばnとしておくべきです。
こうしておけば、メインの一番最初でn=7と一カ所だけ変更すればよいのです。

さらに、次の例のようにしておけばプログラムソースをいじらなくてすみます。

n次式再帰的呼び出し

Dim jyn(12), n As Integer
Dim sousuu As Long
Private Sub CommandButton1_Click()

  n = Cells(2, 11)
  sousuu = 0
  jyunretusakusei (1)

End Sub

Sub jyunretusakusei(g As Integer)

  Dim i As Integer, j As Integer, h As Integer

  For i = 1 To n
    jyn(g) = i
    h = 1
    If g > 1 Then
      For j = 1 To g - 1
        If jyn(g) = jyn(j) Then
          h = 0
          Exit For
        End If
      Next
    End If
    If h = 1 Then
      If g < n Then
        jyunretusakusei (g + 1)
      Else
        sousuua = sousuu Mod 20
        sousuus = Int(sousuu / 20)
        sousuu = sousuu + 1
        If sousuu = 1 Then
          Range("m3:o3").Select
          With Selection
            .HorizontalAlignment = xlGeneral
            .VerticalAlignment = xlCenter
            .WrapText = False
            .Orientation = 0
            .AddIndent = False
            .IndentLevel = 0
            .ShrinkToFit = False
            .ReadingOrder = xlContext
            .MergeCells = True
          End With
          Cells(3, 10) = "順列総数"
          Cells(2, 1).Select
        End If
        Cells(3, 13) = sousuu
        For j = 1 To n
          Cells(5 + sousuus * 2, 1 + j + sousuua * (n + 1)) = jyn(j)
        Next
      End If
    End If
  Next

End Sub

n = Cells(2, 11)でエクセルのK2の数字がnに代入されています。
このように共通な数字は、
具体的な数字で書かないで文字で表すのがこつです。
n = Cells(2, 11)
としておけば、いちいちプログラムソースをいじらないですむのです。
K2に1から12までの数字を入力して実行ボタンを押せば、
1次から12次までの順列ができます。
12を上限にしている理由は、このぐらいになると処理時間が長くなってしまうからです。
理論的には20でも30でもかまわないわけです。

さて、再帰的呼び出しのメリットがわかったかと思います。
私の魔方陣プログラムでは、再帰的方法をあちらこちらで使用しています。
プログラムによって100万次元ループも扱っています。
ループ文ではとても書ききれないものが、
再帰的呼び出しでは簡単にできてしまうのです。

上のプログラム例では少し、部品が大きすぎるようです。
例えば、表示の部分を独立させると次のプログラムになります。
n次順列再帰的呼び出し改良例

プログラム内容の解説は、次話以降で行います。

第1話へ 第3話へ