Java再帰フィボナッチ数列


156

この簡単なコードを説明してください:

public int fibonacci(int n)  {
    if(n == 0)
        return 0;
    else if(n == 1)
      return 1;
   else
      return fibonacci(n - 1) + fibonacci(n - 2);
}

特にn = 5の場合、fibonacci(4)+ fibonacci(3)などが呼び出されるため、最後の行と混同されていますが、このアルゴリズムがインデックス5の値を計算する方法がわかりません方法。細かく説明してください!


8
これは再帰的であり、指数関数的に実行されることに注意してください。Nの値が大きい場合は効率的ではありません。反復的なアプローチを使用して、シーケンスの最初の10,000個の数値を計算することができました。彼らはここで見つけることができます-goo.gl/hnbF5
アダム

@AdamFisher:10,000個の数値を順番に計算するために使用したコードを共有していただけませんか?私は実際にそれを知っている骨董品です。
Shumail 2013年

4
@AdamFisher参照したリンクは無効です。
iRuth 2015

2
このビデオは、10分で再帰関数を理解するために説明しますyoutube.com/watch?v=t4MSwiqfLaY
Chathura Palihakkara

2
あなたにとってそれほど難しくないかもしれない反復的なアプローチもあります。ここにコードがある再帰的および反復的な両方の素晴らしい記事-codeflex.co/java-get-fibonacci-number-by-index
user5495300

回答:


165

フィボナッチシーケンスでは、各項目は前の2つの合計です。したがって、再帰的なアルゴリズムを作成しました。

そう、

fibonacci(5) = fibonacci(4) + fibonacci(3)

fibonacci(3) = fibonacci(2) + fibonacci(1)

fibonacci(4) = fibonacci(3) + fibonacci(2)

fibonacci(2) = fibonacci(1) + fibonacci(0)

今、あなたはすでに知っていfibonacci(1)==1 and fibonacci(0) == 0ます。したがって、後で他の値を計算できます。

さて、

fibonacci(2) = 1+0 = 1
fibonacci(3) = 1+1 = 2
fibonacci(4) = 2+1 = 3
fibonacci(5) = 3+2 = 5

そして、フィボナッチ数列から、フィボナッチ数列0,1,1,2,3,5,8,13,21....に対してが5th element返されることがわかります5

再帰チュートリアルについては、こちらを参照してください。


機能しますが、最適化されるまでは最適化されません。私の答えを見てください。私は提案/コメントの場合は知ってみましょう
Mサックス

52

コードには2つの問題があります。

  1. 結果はintに格納され、最初の48フィボナッチ数のみを処理できます。その後、整数のfillからビットを差し引いた結果が間違っています。
  2. しかし、fibonacci(50)を実行することはできません。
    コード
    fibonacci(n - 1) + fibonacci(n - 2)
    は非常に間違っています。
    問題は、それがフィボナッチを50回ではなく、はるかに呼び出すことです。
    最初はfibonacci(49)+ fibonacci(48)を呼び出し、
    次はfibonacci(48)+ fibonacci(47)およびfibonacci(47)+ fibonacci(46)を呼び出します
    。これは、fibonacci(n)になるたびに悪化するため、複雑さは指数関数的です。 ここに画像の説明を入力してください

非再帰的コードへのアプローチ:

 double fibbonaci(int n){
    double prev=0d, next=1d, result=0d;
    for (int i = 0; i < n; i++) {
        result=prev+next;
        prev=next;
        next=result;
    }
    return result;
}

4
他の回答のいくつかは再帰をより明確に説明していますが、これはおそらくより深いレベルで最も関連性の高い回答です。
Hal50000

1
「整数フィルマイナスビット」とはどういう意味ですか?
リチャード2015

1
@richard、整数の格納方法についてです。intが2 ^ 31-1に達した後、次のビットは符号についてなので、数値は負になります。
2015

はるかに高速で再帰的です。唯一の予約は、n = 1に対して機能しないことです。追加の条件が必要です
v0rin

1
「毎回2 ^ n悪くなった」実際には関数呼び出しの総数は2*fibonacci(n+1)-1なので、フィボナッチ数自体と同じ複雑さで成長します。これは2 ^ nではなく1.618 ^ nです
Aemyl

37

n = 5の疑似コードでは、次のことが行われます。

フィボナッチ(4)+フィボナッチ(3)

これは次のように分類されます。

(フィボナッチ(3)+フィボナッチ(2))+(フィボナッチ(2)+フィボナッチ(1))

これは次のように分類されます。

(((フィボナッチ(2)+フィボナッチ(1))+((フィボナッチ(1)+フィボナッチ(0)))+(((フィボナッチ(1)+フィボナッチ(0))+ 1))

これは次のように分類されます。

((((フィボナッチ(1)+フィボナッチ(0))+ 1)+((1 + 0))+((1 + 0)+ 1))

これは次のように分類されます。

(((((1 + 0)+ 1)+((1 + 0))+((1 + 0)+ 1))

これは次の結果になります:5

フィボナッチ数列が1 1 2 3 5 8 ...の場合、5番目の要素は5です。同じ方法を使用して、他の反復を計算できます。


この答えは質問を最もよく説明すると思います。本当にシンプル
アミット

これはすごいです。n番目の項の値とそれに続く系列の両方を説明します。
セミコロン

12

再帰はときどき把握しにくい場合があります。ほんの数枚の紙でそれを評価してください:

fib(4)
-> fib(3) + fib(2)
-> fib(2) + fib(1) + fib(1) + fib(0)
-> fib(1) + fib(0) + fib(1) + fib(1) + fib(0)
-> 1 + 0 + 1 + 1 + 0
-> 3

Javaがこれを実際にどのように評価するかはわかりませんが、結果は同じになります。


2行目の最後の1と0はどこから来るのですか?
pocockn 2016年

1
@pocockn fib(2)= fib(1)+ fib(0)
tim

したがって、fib(4)があるため、n-1およびn-2はfib(3)+ fib(2)となり、n-1およびn-2を再度実行すると、-> fib(2)+ fib(1 )、どこから+ fib(1)+ fib(0)を取得しましたか?最後に追加
pocockn

@pocockn FIB(2)+ FIB(1)FIB(3)からのものである、FIB(1)+ FIB(0)FIB(2)からのものである
ティム

12

次のように、関数を簡略化することもできます。

public int fibonacci(int n)  {
    if (n < 2) return n;

    return fibonacci(n - 1) + fibonacci(n - 2);
}

これ、これこれこの答えとどう違うのですか?
Tunaki

6
それはただ短くて読みやすく、アルゴリズムは常に=でなければなりません=)
Otavio Ferreira

@OtavioFerreiraは、私の問題を解決するために何とか成功した唯一の答えです。よくできました
KKKKK

8
                                F(n)
                                /    \
                            F(n-1)   F(n-2)
                            /   \     /      \
                        F(n-2) F(n-3) F(n-3)  F(n-4)
                       /    \
                     F(n-3) F(n-4)

注意すべき重要な点は、このアルゴリズムは以前に計算された数値の結果を格納しないため、このアルゴリズムが指数関数的であることです。たとえば、F(n-3)は3回呼び出されます。

詳細については、dasgupta Chapter 0.2によるアルゴリズムを参照してください。


動的プログラミングを使用して同じnに対してF(n)を何度も計算することを回避できるプログラミング方法論があります
Amit_Hora

8

答えのほとんどは適切で、フィボナッチの再帰がどのように機能するかを説明しています。

以下は、再帰を含む3つの手法の分析です。

  1. ループ
  2. 再帰
  3. メモ化

3つすべてをテストするためのコードは次のとおりです。

public class Fibonnaci {
    // Output = 0 1 1 2 3 5 8 13

    static int fibMemo[];

    public static void main(String args[]) {
        int num = 20;

        System.out.println("By For Loop");
        Long startTimeForLoop = System.nanoTime();
        // returns the fib series
        int fibSeries[] = fib(num);
        for (int i = 0; i < fibSeries.length; i++) {
            System.out.print(" " + fibSeries[i] + " ");
        }
        Long stopTimeForLoop = System.nanoTime();
        System.out.println("");
        System.out.println("For Loop Time:" + (stopTimeForLoop - startTimeForLoop));


        System.out.println("By Using Recursion");
        Long startTimeRecursion = System.nanoTime();
        // uses recursion
        int fibSeriesRec[] = fibByRec(num);

        for (int i = 0; i < fibSeriesRec.length; i++) {
            System.out.print(" " + fibSeriesRec[i] + " ");
        }
        Long stopTimeRecursion = System.nanoTime();
        System.out.println("");
        System.out.println("Recursion Time:" + (stopTimeRecursion -startTimeRecursion));



        System.out.println("By Using Memoization Technique");
        Long startTimeMemo = System.nanoTime();
        // uses memoization
        fibMemo = new int[num];
        fibByRecMemo(num-1);
        for (int i = 0; i < fibMemo.length; i++) {
            System.out.print(" " + fibMemo[i] + " ");
        }
        Long stopTimeMemo = System.nanoTime();
        System.out.println("");
        System.out.println("Memoization Time:" + (stopTimeMemo - startTimeMemo));

    }


    //fib by memoization

    public static int fibByRecMemo(int num){

        if(num == 0){
            fibMemo[0] = 0;
            return 0;
        }

        if(num ==1 || num ==2){
          fibMemo[num] = 1;
          return 1; 
        }

        if(fibMemo[num] == 0){
            fibMemo[num] = fibByRecMemo(num-1) + fibByRecMemo(num -2);
            return fibMemo[num];
        }else{
            return fibMemo[num];
        }

    }


    public static int[] fibByRec(int num) {
        int fib[] = new int[num];

        for (int i = 0; i < num; i++) {
            fib[i] = fibRec(i);
        }

        return fib;
    }

    public static int fibRec(int num) {
        if (num == 0) {
            return 0;
        } else if (num == 1 || num == 2) {
            return 1;
        } else {
            return fibRec(num - 1) + fibRec(num - 2);
        }
    }

    public static int[] fib(int num) {
        int fibSum[] = new int[num];
        for (int i = 0; i < num; i++) {
            if (i == 0) {
                fibSum[i] = i;
                continue;
            }

            if (i == 1 || i == 2) {
                fibSum[i] = 1;
                continue;
            }

            fibSum[i] = fibSum[i - 1] + fibSum[i - 2];

        }
        return fibSum;
    }

}

結果は次のとおりです。

By For Loop
 0  1  1  2  3  5  8  13  21  34  55  89  144  233  377  610  987  1597  2584  4181 
For Loop Time:347688
By Using Recursion
 0  1  1  2  3  5  8  13  21  34  55  89  144  233  377  610  987  1597  2584  4181 
Recursion Time:767004
By Using Memoization Technique
 0  1  1  2  3  5  8  13  21  34  55  89  144  233  377  610  987  1597  2584  4181 
Memoization Time:327031

したがって、メモ化が時間的に最適であり、forループが厳密に一致していることがわかります。

しかし、再帰は最も時間がかかり、実際には避けなければならない場合があります。また、再帰を使用している場合は、必ずソリューションを最適化してください。


1
「ここでは、forループが最適な時間であることがわかります」; "ループ時間:347688の場合"; "メモ化時間:327031"; > 327031. 347688
AjahnCharles

@CodeConfidentええ、私は今日その間違いを見ただけでそれを修正しようとしていました。とにかく、ありがとう :)。
Pritam Banerjee 2017

7

これは、Javaでの再帰とフィボナッチ数列を完全に説明する、私が見つけた最高のビデオです。

http://www.youtube.com/watch?v=dsmBRUCzS7k

これは彼のシーケンスのコードであり、彼の説明は私がそれをタイプしようとすることができるよりも優れています。

public static void main(String[] args)
{
    int index = 0;
    while (true)
    {
        System.out.println(fibonacci(index));
        index++;
    }
}
    public static long fibonacci (int i)
    {
        if (i == 0) return 0;
        if (i<= 2) return 1;

        long fibTerm = fibonacci(i - 1) + fibonacci(i - 2);
        return fibTerm;
    }

5

フィボナッチ再帰的解法では、より大きな数の値を取得しながら、より小さなフィボナッチ数の出力を保存することが重要です。これを「メモ化」と呼びます。

次のコードは、小さいフィボナッチ数をメモしながら、大きいフィボナッチ数を取得するコードです。このコードは効率的で、同じ機能に対して複数のリクエストを行いません。

import java.util.HashMap;

public class Fibonacci {
  private HashMap<Integer, Integer> map;
  public Fibonacci() {
    map = new HashMap<>();
  }
  public int findFibonacciValue(int number) {
    if (number == 0 || number == 1) {
      return number;
    }
    else if (map.containsKey(number)) {
      return map.get(number);
    }
    else {
      int fibonacciValue = findFibonacciValue(number - 2) + findFibonacciValue(number - 1);
      map.put(number, fibonacciValue);
      return fibonacciValue;
    }
  }
}

4

フィボナッチシーケンス、最初の2つの項目は、0と1であり、互いにアイテムが前の2つの項目の合計です。すなわち:
0 1 1 2 3 5 8 ...

したがって、5番目の項目は4番目と3番目の項目の合計です。


4

Michael Goodrichらは、[fib(n)、fib(n-1)]の配列を返すことによりフィボナッチを線形時間で再帰的に解決するために、Javaのデータ構造とアルゴリズムで本当に賢いアルゴリズムを提供しています。

public static long[] fibGood(int n) {
    if (n < = 1) {
        long[] answer = {n,0};
        return answer;
    } else {
        long[] tmp = fibGood(n-1);
        long[] answer = {tmp[0] + tmp[1], tmp[0]};
        return answer;
    }
}

これにより、fib(n)= fibGood(n)[0]が生成されます。


4

ここにO(1)ソリューションがあります:

 private static long fibonacci(int n) {
    double pha = pow(1 + sqrt(5), n);
    double phb = pow(1 - sqrt(5), n);
    double div = pow(2, n) * sqrt(5);

    return (long) ((pha - phb) / div);
}

上記の実装に使用されたビネットのフィボナッチ数式。大きな入力のlong場合、で置き換えることができますBigDecimal


3

フィボナッチ数列は、1から始まる前の結果に追加された数値の結果を合計するものです。

      so.. 1 + 1 = 2
           2 + 3 = 5
           3 + 5 = 8
           5 + 8 = 13
           8 + 13 = 21

フィボナッチとは何かを理解したら、コードを分解し始めることができます。

public int fibonacci(int n)  {
    if(n == 0)
        return 0;
    else if(n == 1)
      return 1;
   else
      return fibonacci(n - 1) + fibonacci(n - 2);
}

最初のifステートメントは、ループが発生する可能性がある基本ケースをチェックします。その下のelse ifステートメントも同じことをしていますが、次のように書き直すことができます...

    public int fibonacci(int n)  {
        if(n < 2)
             return n;

        return fibonacci(n - 1) + fibonacci(n - 2);
    }

基本ケースが確立されたので、コールスタックを理解する必要があります。「fibonacci」への最初の呼び出しは、呼び出し元とは逆の順序で解決されるため、スタック(呼び出しのシーケンス)で最後に解決されます。最後に呼び出されたメソッドが最初に解決され、次に最後のメソッドがそのメソッドの前に呼び出されます。

したがって、すべての呼び出しは、これらの結果を使用して何かが「計算」される前に最初に行われます。入力が8の場合、出力は21になるはずです(上の表を参照)。

fibonacci(n-1)は、基本ケースに到達するまで呼び出され続け、その後、基本ケースに到達するまでfibonacci(n-2)が呼び出されます。スタックが逆の順序で結果を合計し始めると、結果は次のようになります...

1 + 1 = 1        ---- last call of the stack (hits a base case).
2 + 1 = 3        ---- Next level of the stack (resolving backwards).
2 + 3 = 5        ---- Next level of the stack (continuing to resolve).

それらは、正しい合計がスタックの最初の呼び出しに返されるまで、バブリング(逆方向に解決)を続け、そのようにして答えが得られます。

とは言っても、このアルゴリズムはコードが分割する各ブランチに対して同じ結果を計算するため、非常に非効率的です。はるかに優れたアプローチは、メモ化(キャッシュ)または再帰(ディープコールスタック)が不要な「ボトムアップ」アプローチです。

そのようです...

        static int BottomUpFib(int current)
        {
            if (current < 2) return current;

            int fib = 1;
            int last = 1;

            for (int i = 2; i < current; i++)
            {
                int temp = fib;
                fib += last;
                last = temp;
            }

            return fib;
        }

2

ここで提供されるソリューションのほとんどは、O(2 ^ n)の複雑さで実行されます。再帰ツリー内の同一ノードを再計算することは非効率的であり、CPUサイクルを浪費します。

メモ化を使用して、フィボナッチ関数をO(n)時間で実行できます。

public static int fibonacci(int n) {
    return fibonacci(n, new int[n + 1]);
}

public static int fibonacci(int i, int[] memo) {

    if (i == 0 || i == 1) {
        return i;
    }

    if (memo[i] == 0) {
        memo[i] = fibonacci(i - 1, memo) + fibonacci(i - 2, memo);
    }
    return memo[i];
}

ボトムアップダイナミックプログラミングルートに従う場合、以下のコードはフィボナッチを計算するのに十分簡単です。

public static int fibonacci1(int n) {
    if (n == 0) {
        return n;
    } else if (n == 1) {
        return n;
    }
    final int[] memo = new int[n];

    memo[0] = 0;
    memo[1] = 1;

    for (int i = 2; i < n; i++) {
        memo[i] = memo[i - 1] + memo[i - 2];
    }
    return memo[n - 1] + memo[n - 2];
}

2

なぜこの答えが違うのか

他のすべての答えのいずれか:

  • 返品の代わりに印刷
  • 反復ごとに2回の再帰呼び出しを行う
  • ループを使用して質問を無視します

(余談:これらのどれも実際には効率的ではありません。Binetの公式を使用して、n 番目の項を直接計算します)

尾の再帰的なFib

これは、前の回答とその前の回答の両方を渡すことにより、二重再帰呼び出しを回避する再帰的アプローチです。

private static final int FIB_0 = 0;
private static final int FIB_1 = 1;

private int calcFibonacci(final int target) {
    if (target == 0) { return FIB_0; }
    if (target == 1) { return FIB_1; }

    return calcFibonacci(target, 1, FIB_1, FIB_0);
}

private int calcFibonacci(final int target, final int previous, final int fibPrevious, final int fibPreviousMinusOne) {
    final int current = previous + 1;
    final int fibCurrent = fibPrevious + fibPreviousMinusOne;
    // If you want, print here / memoize for future calls

    if (target == current) { return fibCurrent; }

    return calcFibonacci(target, current, fibCurrent, fibPrevious);
}

1

1 1 2 3 5 8の出力を表示または取得するのは基本的なシーケンスであり、前の数と現在の数の合計が次に表示されるシーケンスです。

Java再帰フィボナッチシーケンスチュートリアルの下のリンクをご覧ください

public static long getFibonacci(int number){
if(number<=1) return number;
else return getFibonacci(number-1) + getFibonacci(number-2);
}

ここをクリックスプーンの給餌のためのJava再帰フィボナッチシーケンスチュートリアル見る


彼が理解する必要があったのは、コードがどのように機能するか、そしてなぜそれが彼らが書かれているように書かれているのかです。
Adarsh 2013年

私は最初の文でそれがどのように機能するかについて言及していると思いますか?私はそれをより簡単にするためにコードを書きます。ところで、ごめんなさい。
Jaymelson Galang 2013

コードに問題はありません。そのコードがどのように機能するかを理解したかったのは男だけでした。RanRagによる回答を確認してください。そのようなもの:)
Adarsh

ああ、わかりました。申し訳ありませんが、stackoverflowの初心者です。^ _ ^を助けたいだけ
Jaymelson Galang 2013

1

これは簡単な方法だと思います:

public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int number = input.nextInt();
        long a = 0;
        long b = 1;
        for(int i = 1; i<number;i++){
            long c = a +b;
            a=b;
            b=c;
            System.out.println(c);
        }
    }
}

1

RanRag(accepted)の回答は問題なく機能しますが、Anilの回答で説明されているように記憶されるまで、最適化されたソリューションではありません。

以下のアプローチを再帰的に検討する場合、メソッド呼び出しTestFibonacciは最小

public class TestFibonacci {

    public static void main(String[] args) {

        int n = 10;

        if (n == 1) {
            System.out.println(1);

        } else if (n == 2) {
            System.out.println(1);
            System.out.println(1);
        } else {
            System.out.println(1);
            System.out.println(1);
            int currentNo = 3;
            calFibRec(n, 1, 1, currentNo);
        }

    }

    public static void calFibRec(int n, int secondLast, int last,
            int currentNo) {
        if (currentNo <= n) {

            int sum = secondLast + last;
            System.out.println(sum);
            calFibRec(n, last, sum, ++currentNo);
        }
    }

}

1
public class febo 
{
 public static void main(String...a)
 {
  int x[]=new int[15];  
   x[0]=0;
   x[1]=1;
   for(int i=2;i<x.length;i++)
   {
      x[i]=x[i-1]+x[i-2];
   }
   for(int i=0;i<x.length;i++)
   {
      System.out.println(x[i]);
   }
 }
}

1

理論的にはこの再帰的な実装がマルチスレッド環境で適切に動作することを可能にする内部ConcurrentHashMapを使用することにより、BigIntegerとRecursionの両方を使用するfib関数を実装しました。最初の100 fib数の計算には約53msかかります。

private final Map<BigInteger,BigInteger> cacheBig  
    = new ConcurrentHashMap<>();
public BigInteger fibRecursiveBigCache(BigInteger n) {
    BigInteger a = cacheBig.computeIfAbsent(n, this::fibBigCache);
    return a;
}
public BigInteger fibBigCache(BigInteger n) {
    if ( n.compareTo(BigInteger.ONE ) <= 0 ){
        return n;
    } else if (cacheBig.containsKey(n)){
        return cacheBig.get(n);
    } else {
        return      
            fibBigCache(n.subtract(BigInteger.ONE))
            .add(fibBigCache(n.subtract(TWO)));
    }
}

テストコードは次のとおりです。

@Test
public void testFibRecursiveBigIntegerCache() {
    long start = System.currentTimeMillis();
    FibonacciSeries fib = new FibonacciSeries();
    IntStream.rangeClosed(0,100).forEach(p -&R {
        BigInteger n = BigInteger.valueOf(p);
        n = fib.fibRecursiveBigCache(n);
        System.out.println(String.format("fib of %d is %d", p,n));
    });
    long end = System.currentTimeMillis();
    System.out.println("elapsed:" + 
    (end - start) + "," + 
    ((end - start)/1000));
}
テストの出力は次のとおりです。
    。
    。
    。
    。
    。
    93のfibは12200160415121876738です
    94のfibは19740274219868223167です
    95のfibは31940434634990099905
    96のfibは51680708854858323072
    97のfibは83621143489848422977
    98のfibは135301852344706746049です
    99のfibは218922995834555169026です
    100のfibは354224848179261915075
    経過:58,0

1

以下は再帰的な1行のフェボナッチです。

public long fib( long n ) {
        return n <= 0 ? 0 : n == 1 ? 1 : fib( n - 1 ) + fib( n - 2 );
}


0

補足として、より大きな数値を計算できるようにしたい場合は、BigIntegerを使用する必要があります。

反復的な例。

import java.math.BigInteger;
class Fibonacci{
    public static void main(String args[]){
        int n=10000;
        BigInteger[] vec = new BigInteger[n];
        vec[0]=BigInteger.ZERO;
        vec[1]=BigInteger.ONE;
        // calculating
        for(int i = 2 ; i<n ; i++){
            vec[i]=vec[i-1].add(vec[i-2]);
        }
        // printing
        for(int i = vec.length-1 ; i>=0 ; i--){
            System.out.println(vec[i]);
            System.out.println("");
        }
    }
}

0

http://en.wikipedia.org/wiki/Fibonacci_numberの詳細

public class Fibonacci {

    public static long fib(int n) {
        if (n <= 1) return n;
        else return fib(n-1) + fib(n-2);
    }

    public static void main(String[] args) {
        int N = Integer.parseInt(args[0]);
        for (int i = 1; i <= N; i++)
            System.out.println(i + ": " + fib(i));
    }

}

必要なだけシンプルにするため、whileループや他のループを使用する必要はありません。


0
public class FibonacciSeries {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int N = scanner.nextInt();
        for (int i = 0; i <= N; i++) {
            int result = fibonacciSeries(i);
            System.out.println(result);
        }
        scanner.close();
    }

    private static int fibonacciSeries(int n) {
        if (n < 0) {
            return 1;
        } else if (n > 0) {
            return fibonacciSeries(n - 1) + fibonacciSeries(n - 2);
        }
        return 0;
    }
}

0

使用while

public int fib(int index) {
    int tmp = 0, step1 = 0, step2 = 1, fibNumber = 0;
    while (tmp < index - 1) {
        fibNumber = step1 + step2;
        step1 = step2;
        step2 = fibNumber;
        tmp += 1;
    };
    return fibNumber;
}

このソリューションの利点は、コードが読みやすく理解しやすいことです。


0

フィボナッチ数列は、数値の結果を合計するもので、前の結果に追加しました。1から始めます。アルゴリズムに基づいて解決策を見つけようとしていたため、再帰的なコードを作成しました。以前の番号と私は位置を変更しました。1〜15のフィボナッチ数列を検索しています。

public static void main(String args[]) {

    numbers(1,1,15);
}


public static int numbers(int a, int temp, int target)
{
    if(target <= a)
    {
        return a;
    }

    System.out.print(a + " ");

    a = temp + a;

    return numbers(temp,a,target);
}

-1
 public static long fib(int n) {
    long population = 0;

    if ((n == 0) || (n == 1)) // base cases
    {
        return n;
    } else // recursion step
    {

        population+=fib(n - 1) + fib(n - 2);
    }

    return population;
}

-1

シンプルなフィボナッチ

public static void main(String[]args){

    int i = 0;
    int u = 1;

    while(i<100){
        System.out.println(i);
        i = u+i;
        System.out.println(u);
        u = u+i;
    }
  }
}

2
SOへようこそ。あなたの答えはフィボナッチ数列を計算しますが。あなたの答えは、再帰関数について尋ねたOPには答えません。
James K

-2

@chroは適切ですが、これを再帰的に行う正しい方法を示していません。これが解決策です:

class Fib {
    static int count;

    public static void main(String[] args) {
        log(fibWrong(20));  // 6765
        log("Count: " + count); // 21891
        count = 0;
        log(fibRight(20)); // 6765
        log("Count: " + count); // 19
    }

    static long fibRight(long n) {
        return calcFib(n-2, 1, 1);
    }

    static long fibWrong(long n) {
        count++;
        if (n == 0 || n == 1) {
            return n;
        } else if (n < 0) {
            log("Overflow!");
            System.exit(1);
            return n;
        } else {
            return fibWrong(n-1) + fibWrong(n-2);
        }

    }

    static long calcFib(long nth, long prev, long next) {
        count++;
        if (nth-- == 0)
            return next;
        if (prev+next < 0) {
            log("Overflow with " + (nth+1) 
                + " combinations remaining");
            System.exit(1);
        }
        return calcFib(nth, next, prev+next);
    }

    static void log(Object o) {
        System.out.println(o);
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.