2017-07-01 7 views
-4

fib_2()は再帰だとは思わないので、私は友人と議論していますが、それは自分自身を呼び出すためです。
fib_2()には、別のfib_2()の引数として使用するための戻り値がないため、そうは思わないでしょう。 私はfib_2()fib_3()と同じだと思います。それは反復であり、再帰ではありません。これは再帰ですか?そうではありませんか?

これは再帰かどうかですか?

public class Demo { 
    public static void main(String[] args) { 
     System.out.printf("fib_1 -> %d\n", fib_1(10)); 
     System.out.printf("fib_2 -> %d\n", fff(10)); 
     System.out.printf("fib_3 -> %d\n", fib_3(10)); 
    } 

    //This is recursion 
    public static int fib_1(int n) { 
     if (n == 1 || n == 2) 
      return 1; 
     return fib_1(n - 1) + fib_1(n - 2); 
    } 

    //Is this recursion or not ? 
    public static int fff(int n) { 
     int a = 1, b = 1, c = 0, count = 2; 
     return fib_2(a, b, n, c, count); 
    } 

    public static int fib_2(int a, int b, int n, int c, int count) { 
     if (count == n) { 
      return c; 
     } 
     int tmp = b; 
     b = a + b; 
     a = tmp; 
     c = b; 
     ++count; 
     return fib_2(a, b, n, c, count); 
    } 

    public static int fib_3(int n) { 
     int a = 1, b = 1; 

     for (int i = 2; i < n; i++) { 
      int temp = b; 
      b = a + b; 
      a = temp; 
     } 
     return b; 
    } 
} 

答えて

2

fib_2は再帰的です。 fffはそうではありません。

fib_2の最初の呼び出しは、2番目の呼び出しの結果を返します(したがって、 'uses')。

やフォーマル:

再帰は二つの特性によって定義される:答え

  • を生成するために再帰を使用しないシナリオを終了-a

    1. 単純な基本ケース(またはケース)ベースケースに向かって他のすべてのケースを減らす一連のルール

    fib_2内のが最初のプロパティを満たしている場合。 fib_2の呼び出しは2番目の時間を満たします。


    fib_3反復的です。

    fib_2はではないはfib_3と等しい! 2つの関数は、与えられた入力ごとに同じ出力を生成する場合に限り、(数学的に)等しいです! fib_2とfib_3は異なるパラメータを持つため、これは真実ではありません。

    fib_3を使用すると、副作用のようなものを考慮する必要があり、コンピュータサイエンスの方法でfffおよび/または平等のためにfib_1

    に等しくすることができます。

  • +0

    しかし、バックトラッキングはありません – Saber

    +0

    あなたはfib_2コールのスタックを構築しています。ベースケース(count == n)をヒットすると、スタック全体をリターンで戻します。 – MrOerni

    +1

    @Saber fib_2関数の両方を単一の関数として参照しているため、混乱が生じます。 – MrOerni

    5

    fffは、それ自体を呼び出さないため、再帰的ではありません。再帰的な実装を持つfib_2が呼び出されますが、fffメソッドを再帰的にするだけでは不十分です。

    fib_2は、他の一方で、教科書、再帰的である:それはcount == nのための基本ケースを持っており、それがab、およびcの新しい値でfib_2を呼び出す再帰的なブランチを持っています。

    +0

    ですが、バックトラッキングはありません – Saber

    1
    public static int fib_2(int a, int b, int n, int c, int count) { 
         if (count == n) { 
          return c; 
         } 
         int tmp = b; 
         b = a + b; 
         a = tmp; 
         c = b; 
         ++count; 
         return fib_2(a, b, n, c, count); 
        } 
    

    私はこのコードでリクルートが起こっていると思います。

    関連する問題