web-dev-qa-db-fra.com

Fibonacci récursif

J'ai du mal à comprendre pourquoi

#include <iostream>

using namespace std;

int fib(int x) {
    if (x == 1) {
        return 1;
    } else {
        return fib(x-1)+fib(x-2);
    }
}

int main() {
    cout << fib(5) << endl;
}

entraîne une erreur de segmentation. Une fois que x descend à 1, ne devrait-il pas revenir?

34
blcArmadillo

Lorsque x==2 vous appelez fib(1) et fib(0):

return fib(2-1)+fib(2-2);

Considérez ce qui se passera quand fib(0) sera évalué ...

149
Georg Fritzsche

La raison en est que la séquence de Fibonacci commence par deux entités connues, 0 et 1. Votre code ne vérifie que l’une d’elles (une seule).

Changez votre code en 

int fib(int x) {
    if (x == 0)
        return 0;

    if (x == 1)
        return 1;

    return fib(x-1)+fib(x-2);
}

Pour inclure les deux 0 et 1.

39
LiraNuna

Pourquoi ne pas utiliser un algorithme itératif?

int fib(int n)
{
    int a = 1, b = 1;
    for (int i = 3; i <= n; i++) {
        int c = a + b;
        a = b;
        b = c;
    }           
    return b;
}
11
Dzmitry Huba

Par définition, les deux premiers chiffres de la séquence de Fibonacci sont 1 et 1, ou 0 et 1. Par conséquent, vous devez le gérer.

#include <iostream>
using namespace std;

int Fibonacci(int);

int main(void) {
    int number;

    cout << "Please enter a positive integer: ";
    cin >> number;
    if (number < 0)
        cout << "That is not a positive integer.\n";
    else
        cout << number << " Fibonacci is: " << Fibonacci(number) << endl;
}

int Fibonacci(int x) 
{
    if (x < 2){
     return x;
    }     
    return (Fibonacci (x - 1) + Fibonacci (x - 2));
}
7
Vanji

Je pense que cette solution est courte et semble bien paraître: 

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

Edit: comme mentionné par jweyrich, la vraie fonction récursive devrait être: 

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

(parce que fib (0) = 0. mais en se basant sur la formule récursive ci-dessus, fib (0) sera 1)

Pour comprendre l’algorithme de récursivité, vous devez dessiner sur votre papier, et le plus important est: "Pensez comme d'habitude".

3
hqt

Ceci est ma solution au problème de fibonacci avec la récursivité.  

#include <iostream>
using namespace std;

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

int main() {
    cout << fibonacci(8);
    return 0;
}
3
Pedro Eugénio
int fib(int n) {
    if (n == 1 || n == 2) {
        return 1;
    } else {
        return fib(n - 1) + fib(n - 2);
    }
}

dans la séquence fibonacci, les 2 premiers nombres sont toujours suivis de 1, puis chaque fois que la valeur devient 1 ou 2, elle doit renvoyer 1

2
noelyahan
int fib(int x) 
{
    if (x < 2)
      return x;
    else 
      return (fib(x - 1) + fib(x - 2));
}
1
zod
int fib(int x) 
{
    if (x == 0)
      return 0;
    else if (x == 1 || x == 2) 
      return 1;
    else 
      return (fib(x - 1) + fib(x - 2));
}
1
user2331083
if(n==1 || n==0){
    return n;
}else{     
    return fib(n-1) + fib(n-2);
}

Cependant, utiliser la récursivité pour obtenir le numéro de fibonacci est une mauvaise pratique, car la fonction est appelée environ 8,5 fois plus que le nombre reçu. obtenir le nombre de fibonacci de 30 (1346269) - la fonction s'appelle 7049122 fois!

1
Jokerius

Je pense que c'est la meilleure solution de fibonacci en utilisant la récursivité.

#include<bits/stdc++.h>
typedef unsigned long long ull;
typedef long long ll;
ull FIBO[100005];
using namespace std;
ull fibo(ull n)
{
    if(n==1||n==0)
        return n;
    if(FIBO[n]!=0)
        return FIBO[n];
    FIBO[n] = (fibo(n-1)+fibo(n-2));
    return FIBO[n];
}
int main()
{
    for(long long  i =34;i<=60;i++)
        cout<<fibo(i)<<" " ;
    return 0;
}
0
Md. Ashraful Haque

Ma solution est:

#include <iostream>


    int fib(int number);

    void call_fib(void);

    int main()
    {
    call_fib();
    return 0;
    }

    void call_fib(void)
    {
      int input;
      std::cout<<"enter a number\t";
      std::cin>> input;
      if (input <0)
      {
        input=0;
        std::cout<<"that is not a valid input\n"   ;
        call_fib();
     }
     else 
     {
         std::cout<<"the "<<input <<"th fibonacci number is "<<fib(input);
     }

    }





    int fib(int x)
    {
     if (x==0){return 0;}
     else if (x==2 || x==1)
    {
         return 1;   
    }

    else if (x>0)
   {
        return fib(x-1)+fib(x-2);
    }
    else 
     return -1;
    }

il retourne fib (0) = 0 et erreur si négatif

0
Cadence Weddle

Je pense que toutes ces solutions sont inefficaces. Ils nécessitent beaucoup d'appels récursifs pour obtenir le résultat.

unsigned fib(unsigned n) {
    if(n == 0) return 0;
    if(n == 1) return 1;
    return fib(n-1) + fib(n-2);
}

Ce code nécessite 14 appels pour obtenir le résultat pour fib (5), 177 pour fin (10) et 2,7kk pour fib (30).

Vous devriez mieux utiliser this ou si vous voulez utiliser la récursivité, essayez ceci:

unsigned fib(unsigned n, unsigned prev1 = 0, unsigned prev2 = 1, int depth = 2)     
{
    if(n == 0) return 0;
    if(n == 1) return 1;
    if(depth < n) return fib(n, prev2, prev1+prev2, depth+1);
    return prev1+prev2;
}

Cette fonction nécessite n appels récursifs pour calculer le nombre de Fibonacci pour n. Vous pouvez toujours l'utiliser en appelant fib (10) car tous les autres paramètres ont des valeurs par défaut.