web-dev-qa-db-fra.com

Fonction d'algorithme pour les séries de fibonacci

Je ne cherche pas nécessairement une réponse, mais je cherche ce que cette question demande. Vous avez trouvé cette question en étudiant pour une entrevue, mais vous ne savez pas ce qu'ils demandent?

Fonction d'écriture qui parcourt la séquence de Fibonacci et retourne l'index transmis en tant que paramètre.

8
KingKongFrog

tout d'abord, vous pouvez mettre à jour vos informations mathématiques de base sur Fibonacci avec ce lien du wiki. et regardez cette formule pour un calcul rapide. et vous pouvez tout lire à ce sujet dans ce lien .

C'est une fonction récursive pour calculer le nième nombre de Fibonacci et est de temps O (2 ^ n):

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

Calcul de la séquence

Vous pourriez faire valoir qu'en termes de calcul des valeurs de la séquence de Fibonacci sur un ordinateur, il vaut mieux utiliser la relation de récurrence d'origine, f [n] = f [n − 1] + f [n − 2]. Je suis enclin à accepter. Pour utiliser la solution directe de forme fermée pour les grands n, vous devez conserver beaucoup de précision. Même avec 9 décimales, fn≈round (0,723606798⋅ (1,618033989) n), par exemple, n'est valable que jusqu'à n = 38 (observez ici versus ici ). De plus, l'ajout d'entiers est beaucoup moins coûteux en termes de calcul et plus précis que l'exponentiation d'une fraction symbolique ou d'une valeur à virgule flottante

c'est une meilleure idée pour calculer le nième nombre de Fibonacci et est de O(n) fois:

int Fibonacci(int n) { 
if(n <= 0) return 0;
if(n > 0 && n < 3) return 1;

int result = 0;
int preOldResult = 1;
int oldResult = 1;

for (int i=2;i<n;i++) { 
    result = preOldResult + oldResult;
    preOldResult = oldResult;
    oldResult = result;
}

return result;}

et c'est la meilleure façon de calculer le nième nombre de Fibonacci et est de O(log(n)) temps:

ce lien:

Comme vous le soupçonnez déjà, cela fonctionnera de manière très similaire. Utilisez la nième puissance du x * x matrice

|1 0 0 0  .... 1 1|
|1 
|  1
|    1
|      1
|        1
...................
...................
|          ... 1 0|

C'est facile à comprendre si vous multipliez cette matrice par le vecteur

f(n-1), f(n-2), ... , f(n-x+1), f(n-x)

ce qui se traduit par

f(n), f(n-1), ... , f(n-x+1)

L'exponentiation matricielle peut être effectuée en O(log(n)) temps (lorsque x est considéré comme constant).

Pour la récurrence de Fibonacci, il existe également une solution de formule fermée, voir ici http://en.wikipedia.org/wiki/Fibonacci_number , recherchez la formule de Binet ou Moivre.

et regardez: 1 - nième nombre de fibonacci en temps sublinéaire

30
amin k

Il me semble que l'on vous demande de renvoyer le nième fibonacci n °, où n est le paramètre passé. Vous pouvez utiliser différentes méthodes pour répondre à cette question, alors que toutes ces méthodes varient en complexité temporelle et en complexité de code.

Méthode 1 (Utiliser la récursivité) Une méthode simple qui est une relation de récurrence mathématique de mise en œuvre directe de la récusive donnée ci-dessus.

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

Complexité temporelle: T(n) = T(n-1) + T(n-2) qui est exponentielle. On peut observer que cette implémentation fait beaucoup de travail répété (voir l’arbre de récursivité suivant). C’est donc une mauvaise implémentation pour le nième nombre de Fibonacci.

                     fib(5)   
                 /             \     
           fib(4)                fib(3)   
         /      \                /     \
     fib(3)      fib(2)         fib(2)    fib(1)
    /     \        /    \       /    \  

fib (2) fib (1) fib (1) fib (0) fib (1) fib (0)/\ fib (1) fib (0) Espace supplémentaire: O(n) si l'on considère la taille de la pile d'appels de distinction, sinon O (1).

Méthode 2 (Utiliser la programmation dynamique) Nous pouvons éviter le travail répété effectué est la méthode 1 en stockant les nombres de Fibonacci calculés jusqu'ici.

int fib(int n)
{
     /* Declare an array to store fibonacci numbers. */
      int f[n+1];
      int i;

     /* 0th and 1st number of the series are 0 and 1*/
     f[0] = 0;
     f[1] = 1;

    for (i = 2; i <= n; i++)
    {
       /* Add the previous 2 numbers in the series
        and store it */
       f[i] = f[i-1] + f[i-2];
    }

    return f[n];
}

Complexité temporelle: O(n) Espace supplémentaire: O (n)

Méthode 3 (Space Otimized Method 2) Nous pouvons optimiser l'espace utilisé dans la méthode 2 en stockant les deux nombres précédents uniquement parce que c'est tout ce dont nous avons besoin pour obtenir le prochain nombre de Fibannaci en série.

 int fib(int n)
 {
      int a = 0, b = 1, c, i;
      if( n == 0)
       return a;
      for (i = 2; i <= n; i++)
      {
        c = a + b;
        a = b;
       b = c;
    }
    return b;
  }

Complexité temporelle: O(n) Espace supplémentaire: O (1)

Méthode 4 (en utilisant la puissance du matrx {{1,1}, {0,1}}) Cette autre O(n) qui repose sur le fait que si nous multiplions n fois la matrice M = {{1,1}, {0,1}} à lui-même (en d'autres termes, calculer la puissance (M, n)), alors nous obtenons le (n + 1) ème nombre de Fibonacci comme élément à la ligne et à la colonne ( 0, 0) dans la matrice résultante.

La représentation matricielle donne l'expression fermée suivante pour les nombres de Fibonacci:

  /* Helper function that multiplies 2 matricies F and M of size 2*2, and
    puts the multiplication result back to F[][] */
  void multiply(int F[2][2], int M[2][2]);

  /* Helper function that calculates F[][] raise to the power n and puts the
    result in F[][]
    Note that this function is desinged only for fib() and won't work as general
    power function */
  void power(int F[2][2], int n);

  int fib(int n)
  {
    int F[2][2] = {{1,1},{1,0}};
    if(n == 0)
        return 0;
    power(F, n-1);

    return F[0][0];
  }

  void multiply(int F[2][2], int M[2][2])
  {
    int x =  F[0][0]*M[0][0] + F[0][1]*M[1][0];
    int y =  F[0][0]*M[0][1] + F[0][1]*M[1][1];
    int z =  F[1][0]*M[0][0] + F[1][1]*M[1][0];
    int w =  F[1][0]*M[0][1] + F[1][1]*M[1][1];

    F[0][0] = x;
    F[0][1] = y;
    F[1][0] = z;
    F[1][1] = w;
  }

  void power(int F[2][2], int n)
  {
    int i;
    int M[2][2] = {{1,1},{1,0}};

    // n - 1 times multiply the matrix to {{1,0},{0,1}}
    for ( i = 2; i <= n; i++ )
        multiply(F, M);
  }

Complexité temporelle: O(n) Espace supplémentaire: O (1)

Méthode 5 (méthode optimisée 4) La méthode 4 peut être optimisée pour fonctionner dans une complexité de temps O(Logn). Nous pouvons effectuer une multiplication récursive pour obtenir la puissance (M, n) dans la méthode précédente ( Similaire à l'optimisation effectuée dans ce post)

  void multiply(int F[2][2], int M[2][2]);

  void power(int F[2][2], int n);

  /* function that returns nth Fibonacci number */
  int fib(int n)
  {
    int F[2][2] = {{1,1},{1,0}};
    if(n == 0)
      return 0;
    power(F, n-1);
    return F[0][0];
  }

  /* Optimized version of power() in method 4 */
  void power(int F[2][2], int n)
  {
    if( n == 0 || n == 1)
        return;
    int M[2][2] = {{1,1},{1,0}};

    power(F, n/2);
    multiply(F, F);

    if( n%2 != 0 )
       multiply(F, M);
  }

  void multiply(int F[2][2], int M[2][2])
  {
    int x =  F[0][0]*M[0][0] + F[0][1]*M[1][0];
    int y =  F[0][0]*M[0][1] + F[0][1]*M[1][1];
    int z =  F[1][0]*M[0][0] + F[1][1]*M[1][0];
    int w =  F[1][0]*M[0][1] + F[1][1]*M[1][1];

    F[0][0] = x;
    F[0][1] = y;
    F[1][0] = z;
    F[1][1] = w;
  }

Complexité temporelle: O(Logn) Espace supplémentaire: O(Logn) si nous considérons la taille de la pile d'appels de fonction, sinon O (1).

Programme de pilote: int main () {int n = 9; printf ("% d", fib (9)); getchar (); retourner 0; }

Références: http://en.wikipedia.org/wiki/Fibonacci_numberhttp://www.ics.uci.edu/~eppstein/161/960109.html

13
Aman Chhabra

C'est une question très mal formulée, mais vous devez supposer qu'ils demandent le ne Numéro de Fibonnaci où n est fourni comme paramètre.

En plus de toutes les techniques répertoriées par d'autres, pour n > 1 vous pouvez également utiliser la méthode du nombre d'or , qui est plus rapide que toute méthode itérative. Mais comme la question dit "parcourir la séquence de Fibonacci", cela peut ne pas être admissible. Vous les feriez probablement aussi peur à mort.

2
user207421
public static int fibonacci(int i){
if(i==0)
  return 0;

if(i==1)
   return 1;
return fib(--i,0,1);
}


public static int fib(int num,int pre,int prepre){
   if(num==0){
    return prepre+pre;
   }
    return fib(--num,pre+prepre,pre);
}
0
Dima

J'interprète la question différemment .... étant donné un number en entrée, quel est le index de ce nombre dans la série? par exemple. input=5, puis l'index est 5 (étant donné que la séquence est 0 1 1 2 3 5 où l'index commence par 0)

Ce code est le suivant (qui retourne l'index) [Avertissement: Adapté du code donné à http://talkbinary.com/programming/c/fibonacci-in-c/ ]

int Fibonacci(int n)
{
  if ( n == 0 )
    return 0;
  if ( n== 1 )
    return 1;

  int fib1 = 0; 
  int fib2 = 1;
  int fib = 0;
  int i = 0;

for (i = 2; ; i++ ) 
{

    fib = fib1 + fib2;
    if ( n == fib )
       break;
    fib1 = fib2;
    fib2 = fib;
}


  return i;
}
0
Bill