LoginSignup
4
4

More than 5 years have passed since last update.

SICPより反復と再帰

Last updated at Posted at 2012-11-30

#include <stdio.h>

int Sum0(int start, int end)
{
    int sum = 0;
    for( ; start <= end ; ++start)
    {
        sum += start;
    }
    return sum;
}

int Sum1(int start, int end)
{
    if(start <= end)
    {
        return start + Sum1(start + 1, end);
    }
    else
    {
        return 0;
    }
}

int Sum2(int sum, int start, int end)
{
    if(start <= end)
    {
        return Sum2(sum + start, start + 1, end);
    }
    else
    {
        return sum;
    }
}


int main(int argc, const char * argv[])
{
    printf("%d\n", Sum0(1, 5));
    printf("%d\n", Sum1(1, 5));
    printf("%d\n", Sum2(0, 1, 5));


    /*
     Sum1(1, 5)
     = 1 + Sum1(2, 5)
     = 1 + 2 + Sum1(3, 5)
     = 1 + 2 + 3 + Sum1(4, 5)
     = 1 + 2 + 3 + 4 + Sum1(5, 5)
     = 1 + 2 + 3 + 4 + 5 + Sum1(6, 5)
     = 1 + 2 + 3 + 4 + 5 + 0
     = 15

     Sum2(0, 1, 5)
     = Sum2(0 + 1, 1 + 1, 5) = Sum2(1, 2, 5)
     = Sum2(1 + 2, 2 + 1, 5) = Sum2(3, 3, 5)
     = Sum2(3 + 3, 3 + 1, 5) = Sum2(6, 4, 5)
     = Sum2(6 + 4, 4 + 1, 5) = Sum2(10, 5, 5)
     = Sum2(10 + 5, 5 + 1, 5) = Sum2(15, 6, 5)
     = 15;
     */
    return 0;
}

SICPからのネタです。
1から5の合計を愚直に求める関数をテーマに反復と再帰の構造を考えてみます。
非常に面白いです。こんな考え方があったとは。
誰にでも分かるようにメモします。

まず、すごく手続き型的に考えて、Sum0があります。
for文をつかったまあ分かりやすいプログラムですね。これはいいでしょう。

次に再帰的な関数呼び出しです。
これは少々再帰関数に慣れていないと読みづらいと思います。
しかしこれは展開すると簡単にわかります。

Sum1(1, 5)
を呼び出すということは、次に
1 + Sum1(2, 5)
と展開することができます。そして次に
1 + 2 + Sum1(3, 5)
と、このようにどんどん展開していくことができます。
最後はSum1(6, 5)これは0になるようにifで仕込んであるので、
= 1 + 2 + 3 + 4 + 5 + 0
と展開されるので15になるわけですね。

さて、次が面白いです。
一つ引数が増えています。sumですね。
これは、関数を呼ぶたびに加算した上でスタックに積み続けます。
日本語にするとわけがわからないよ、となりますね。
なので、これも展開してみます。

Sum2(0, 1, 5)
これは次の関数を呼び出すときに2つのことを行います。
1、sumにstartを足す
2、startに1を足す
すると、
Sum2(1, 2, 5)
となります。
これはつまり、ここのsumは、関数Sum0のsum変数とほぼ同等の役割を果たしているわけです。計算をしながら次の関数を呼び出しているんですね。
「再帰関数ではあるが、反復的な構造をしている」
というちょっと不思議な気分です。 
同じ再帰関数でありながら、Sum1とSum2はまったく違う構造で問題を解決しているんですね。実に面白いと思いませんでしょうか。

さて、これは何の役に立つのでしょうか?
自分にはわからないのでもうすこしSICP読みましょうかね。

4
4
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4