VBA

【VBA】再帰処理、再帰関数をVBAで実装する(アルゴリズム)

記事内に商品プロモーションを含む場合があります

このページでわかること

アルゴリズムの記述で出現する再帰的定義という概念をVBAで記述できるようになります。
再帰的定義とはアルゴリズムに自分自身を引用する方法で、
階乗や複利の計算をFor文を使わずにすっきりかくことができます。

こんにちは、hokkyokunです。

プログラミングを実装していく中で、必須ではないが、
あると格段にレベルが上がる概念の一つに、
アルゴリズムの理解があります。

さらにアルゴリズムをプログラミングで記述するためには、
再帰的定義を理解し、再帰関数を作成する必要がある場合が多くあります。

なんだか、難しい話ですが、
覚えるとアルゴリズムの利用範囲が広がり、効率的なプログラムが書けるようになります。

私も勉強中ですが、覚えたことを共有したいと思います。

アルゴリズムとは

例えば、1~100の間の数値を推定していく際に、
1?、2?、3?と一つずつ確認していくと計算量が膨大ですが、

1~50?それとも51~100?
1~50の場合はさらに1~25?それとも26~50?
と確認していった方が計算量が少なく、推定をすることができます。

アリゴリズムとの出会い

私がアルゴリズムのすごさを初体験したのは下記のユーチューブの動画です。

出演なさっている、米田優峻さんは
国内最大の競技プログラミングコンテストサイト「AtCoder」で最高ランクの称号をお持ちで、
国際情報オリンピックで金メダルを三度獲得されている現役東大生です。

この動画でアルゴリズムの威力を素人にもわかり易く解説していただいておりますので、
是非見ていってください。

再帰的定義

アルゴリズムをプログラムに落とし込むための考え方として
再帰的定義という概念を理解する必要があります。

これはプログラム内で自分自身を呼び出し、引用していく手法です。

文字で言ってもよくわからないと思うので、有名な例を紹介したいと思います。

5の階乗をプログラムする

階乗とは5×4×3×2×1というように、数値を一つずつ減らして掛け算することを指します。

これをプログラムで記述するには以下のように処理を考えます。

Nの階乗を考えるとき

  • Nが1になったら1を返す
  • Nが2以上の場合は、((N-1のときの戻り値) × N)を返す

コードは以下の通りです。

Function Factorial(n As Long)
    If n <= 1 Then
        Factorial = n
    Else
        Factorial = n * Factorial(n - 1)
    End If
End Function

Sub test()
    Dim result As Long
    result = Factorial(5)
    Debug.Print result
End Sub

Subプロシージャを動かすと120(=5の階乗)が値として返ってきます。

私は最初何が起こっているのかよくわからなかったので、プログラムの動きを追ってみます。

  1. Factorial(5)を呼び出す
  2. n=5>1なので、5行目のFactorial = n * Factorial(n – 1) でFactorial(4)を呼び出す
  3. n=4>1なので、5行目のFactorial = n * Factorial(n – 1) でFactorial(3)を呼び出す
  4. n=3>1なので、5行目のFactorial = n * Factorial(n – 1) でFactorial(2)を呼び出す
  5. n=2>1なので、5行目のFactorial = n * Factorial(n – 1) でFactorial(1)を呼び出す
  6. n=1<=1なので、3行目のFactorial = n で 1を返す(=Factorial(1)の戻り値は1)
  7. 5.の処理の戻り値計算 1(=Factorial(1))とn(=2)で1×2
  8. 4.の処理の戻り値計算 1×2(=Factorial(2))とn(=3)で1×2×3
  9. 3.の処理の戻り値計算 1×2×3(=Factorial(3))とn(=4)で1×2×3×4
  10. 2.の処理の戻り値計算 1×2×3×4(=Factorial(4))とn(=5)で1×2×3×4×5=120 ⇒Factorial(5)の戻り値

文章で書いてもなかなかイメージ難しいかもですが、
コードを動かしながらこの記述を追うと少し理解に役立つかもしれません。

余談ですが、自分はこの文章を書いているときにやっと腹落ちしました。

ちょっとだけ実生活に役立つ処理

正直階乗計算くらいならfor文、while文で十分だと思います。

ただ、これがないとうまくいかない処理も多く、
ソート(並び替え:いつか記事にします!!)をプログラムで実現するためには、
おそらく再帰関数以外で書くのはかなり困難だと思います。

ソートは難しいので、また別の機会にするとし、
複利計算のマクロを再帰関数で作ってみたいと思います。

'principal : 元金
'rate : 利率(20%の場合は0.2と記入)
'n : 回数
'例えば年利20%で100円を元手に7年運用する場合calc_Interest(100,0.2,7)とする
Function calc_Interest(principal As Long, rate As Double, n As Long)
    If n <= 1 Then
        calc_Interest = principal
    Else
        calc_Interest = (1 + rate) * calc_Interest(principal, rate, n - 1)
    End If
End Function

Sub test2()
    Dim result As Double
    result = calc_Interest(100, 0.2, 7)
    Debug.Print result
End Sub

さらに勉強したい方

複利の計算がこんなに簡単にできるのは、目からうろこでした。

知らなくても、なんとなくコード書いて処理はできますが、
アルゴリズムやそれに付随する知識、技術があるとプログラムの可能性は大きく飛躍します。

まじでプログラマー(プロだろうが、アマチュア事務職だろうが)にとって、チートツールになるんじゃないかと思っています。

ぜひぜひ、米田さんの本で勉強してみてください。

ぜひぜひ、第二段第三弾と本を執筆いただき、我々にアルゴリズムをわかりやすく解説いただきたいなと思いました!

ではでは。