160 votes

Suite récursive de Fibonacci en Java

Veuillez expliquer ce code simple :

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

Je suis confus avec la dernière ligne surtout parce que si n = 5 par exemple, alors fibonacci(4) + fibonacci(3) serait appelé et ainsi de suite mais je ne comprends pas comment cet algorithme calcule la valeur à l'indice 5 par cette méthode. Veuillez m'expliquer avec beaucoup de détails !

10 votes

Notez que ceci est récursif et s'exécute en temps exponentiel. C'est inefficace pour les grandes valeurs de N. En utilisant une approche itérative, j'ai pu calculer les 10 000 premiers nombres de la séquence. Ils peuvent être trouvés ici - goo.gl/hnbF5

0 votes

@AdamFisher : Pouvez-vous partager le code que vous avez utilisé pour calculer 10.000 nombres en séquence ? Je suis vraiment curieux de le connaître.

4 votes

@AdamFisher Le lien auquel vous faites référence est mort.

169voto

RanRag Points 9395

Dans la suite de Fibonacci, chaque élément est la somme des deux précédents. Donc, vous avez écrit un algorithme récursif.

Donc,

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

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

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

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

Maintenant, vous savez déjà fibonacci(1)==1 and fibonacci(0) == 0 . Vous pouvez donc calculer les autres valeurs par la suite.

Maintenant,

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

Et de la séquence de Fibonacci 0,1,1,2,3,5,8,13,21.... nous pouvons voir que pour 5th element la séquence de fibonacci revient 5 .

Voir ici pour Tutoriel sur la récursion .

0 votes

Il fonctionnera mais ne sera pas optimisé tant qu'il ne sera pas optimisé. Jetez un coup d'oeil à ma réponse. Faites-moi savoir si vous avez des suggestions/commentaires.

54voto

chro Points 697

Il y a deux problèmes avec votre code :

  1. Le résultat est stocké dans int qui ne peut traiter que les 48 premiers nombres de fibonacci, après cela l'entier remplit le bit moins et le résultat est faux.
  2. Mais vous ne pouvez jamais exécuter fibonacci(50).
    Le code
    fibonacci(n - 1) + fibonacci(n - 2)
    est très mauvaise.
    Le problème est qu'il appelle Fibonacci non pas 50 fois mais beaucoup plus.
    Au début, il appelle fibonacci(49)+fibonacci(48),
    suivant fibonacci(48)+fibonacci(47) et fibonacci(47)+fibonacci(46)
    A chaque fois, il est devenu fibonacci(n) pire, donc la complexité est exponentielle. enter image description here

L'approche du code non-récursif :

 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 votes

Bien que certaines des autres réponses expliquent plus clairement la récursion, cette réponse est probablement la plus pertinente à un niveau plus profond.

1 votes

Que signifie "remplissage entier moins bit" ?

1 votes

Richard, il s'agit de la façon dont les entiers sont stockés. Après que l'entier ait atteint 2^31-1, le bit suivant concerne le signe, donc le nombre devient négatif.

41voto

brainzzy Points 1966

En pseudo-code, où n = 5, le processus suivant se déroule :

fibonacci(4) + fibonnacci(3)

Cela se décompose en :

(fibonacci(3) + fibonnacci(2)) + (fibonacci(2) + fibonnacci(1))

Cela se décompose en :

(((fibonacci(2) + fibonnacci(1)) + ((fibonacci(1) + fibonnacci(0))) + (((fibonacci(1) + fibonnacci(0)) + 1))

Cela se décompose en :

((((fibonacci(1) + fibonnacci(0)) + 1) + ((1 + 0)) + ((1 + 0) + 1))

Cela se décompose en :

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

Cela se traduit par : 5

Étant donné que la séquence de Fibonnacci est 1 1 2 3 5 8 ... Vous pouvez utiliser la même méthodologie pour déterminer les autres itérations.

0 votes

Je pense que cette réponse explique les questions de la meilleure façon. Vraiment simple

0 votes

C'est très bien. Explique à la fois la valeur au nième terme et la série qu'elle suit.

13voto

tim Points 627

La récursion peut être difficile à appréhender parfois. Il suffit de l'évaluer sur une feuille de papier pour un petit nombre :

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

Je ne sais pas exactement comment Java évalue cela, mais le résultat sera le même.

0 votes

Sur la deuxième ligne, d'où viennent le 1 et le 0 à la fin ?

1 votes

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

0 votes

Donc vous avez fib (4) donc n-1 et n-2 seraient fib(3) + fib(2) puis vous refaites n-1 et n-2 vous obtenez -> fib(2) + fib(1), d'où vient le + fib(1) + fib(0) ? Ajouté à la fin

7voto

user2718538 Points 31

C'est la meilleure vidéo que j'ai trouvée qui explique de manière complète la récursion et la séquence de Fibonacci en Java.

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

C'est son code pour la séquence et son explication est meilleure que ce que je pourrais faire en essayant de la taper.

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;
    }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X