2009-07-02 8 views
2

Je pratique une application de console C#, et j'essaye d'obtenir la fonction pour vérifier si le nombre apparaît dans une série de fibonacci ou pas mais j'obtiens des erreurs.C# fonction fibonacci retournant des erreurs

Ce que je ne faisais que:

class Program 
{ 
    static void Main(string[] args) 
    { 
     System.Console.WriteLine(isFibonacci(20)); 
    } 
    static int isFibonacci(int n) 
    { 
     int[] fib = new int[100]; 
     fib[0] = 1; 
     fib[1] = 1; 
     for (int i = 2; i <= 100; i++) 
     { 
      fib[i] = fib[i - 1] + fib[i - 2]; 

      if (n == fib[i]) 
      { 
       return 1; 
      } 



     } 
     return 0; 
    } 
} 

Quelqu'un peut-il me dire ce que je fais mal ici?

+1

Définir "erreurs" ... –

+0

Vouliez-vous dire erreurs #DEFINE? – Jonathan

+2

Juste curieux, mais pourquoi renvoyez-vous un int plutôt qu'un bool? – Joel

Répondre

5

Et voici une solution qui bat tous les vôtres!

Parce que, pourquoi itération lorsque vous avez intelligents mathématiciens font solutions de forme fermée pour vous?:)

static bool IsFibonacci(int number) 
{ 
    //Uses a closed form solution for the fibonacci number calculation. 
    //http://en.wikipedia.org/wiki/Fibonacci_number#Closed-form_expression 

    double fi = (1 + Math.Sqrt(5))/2.0; //Golden ratio 
    int n = (int) Math.Floor(Math.Log(number * Math.Sqrt(5) + 0.5, fi)); //Find's the index (n) of the given number in the fibonacci sequence 

    int actualFibonacciNumber = (int)Math.Floor(Math.Pow(fi, n)/Math.Sqrt(5) + 0.5); //Finds the actual number corresponding to given index (n) 

    return actualFibonacciNumber == number; 
} 
4

Eh bien, pour commencer votre tableau est seulement 10 long et vous remplissez avec environ 100 articles (hors gamme exception) - mais il y a de meilleures façons de le faire ...

pour par exemple, en utilisant this post:

long val = ... 
bool isFib = Fibonacci().TakeWhile(x => x <= val).Last() == val; 
+0

Ah, vous me battez! – Joseph

+0

oh désolé les gars mon mauvais, c'était une faute de frappe mais ce n'est pas le problème ... – jarus

2

une chose que vous pouvez faire est de vérifier pour une sortie précoce. Puisque vous essayez de déterminer si un nombre donné est dans la séquence de Fibonacci, vous pouvez faire des bornes en vérifiant de quitter tôt.

Exemple:

static bool isFibonacci(int n) 
{ 
    int[] fib = new int[100]; 
    fib[0] = 1; 
    fib[1] = 1; 
    for (int i = 2; i <= fib.Length; i++) 
    { 
     fib[i] = fib[i - 1] + fib[i - 2]; 

     if (n == fib[i]) 
     { 
      return true; 
     } 
     else if (n < fib[i]) 
     { 
      return false; //your number has been surpassed in the fib seq 
     } 
    } 
    return false; 
} 
+1

Probablement devrait jeter une exception si la fin du tableau est remplie: la fonction n'est pas capable de donner une réponse dans ce cas. – Richard

2
int[] fib = new int[10]; 
for (int i = 2; i <= *100*; i++) 

Vous sortez des limites de votre tableau parce que votre boucle conditionnelle est trop grande. Une approche plus traditionnelle serait de lié la boucle par la taille du tableau:

for (int i = 2; i < fib.Length; i++) 

Et faire votre choix plus grand, mais comme Marc dit, il y a de meilleures façons de faire, et je vous conseille de passer un peu temps à lire l'article wikipedia sur Fibonacci numbers.

18

est ici une solution amusante en utilisant un bloc itérateur infini:

IEnumerable<int> Fibonacci() 
{ 
    int n1 = 0; 
    int n2 = 1; 

    yield return 1; 
    while (true) 
    { 
     int n = n1 + n2; 
     n1 = n2; 
     n2 = n; 
     yield return n; 
    } 
} 

bool isFibonacci(int n) 
{ 
    foreach (int f in Fibonacci()) 
    { 
     if (f > n) return false; 
     if (f == n) return true; 
    } 
} 

En fait, je aime vraiment ce genre de mise en œuvre de Fibonacci vs la tradition solution récurrente, car elle conserve le travail utilisé pour compléter un terme disponible pour compléter la prochain. La solution récursive traditionnelle duplique certains travaux, car elle nécessite deux appels récursifs chaque terme.

9

Le problème réside dans < = la déclaration suivante:

for (int i = 2; i <= 100; i++) 

plus au point les =. Il n'y a pas de fib [100] (nombre de zéro C#) donc quand vous vérifiez sur i = 100 vous obtenez une exception.

la déclaration appropriée devrait être

for (int i = 2; i < 100; i++) 

ou mieux encore

for (int i = 2; i < fib.Length; i++) 
+1

+1 Je suis étonné que la réponse la plus élevée et la réponse acceptée ne signalent pas la raison de l'erreur. ** C'est le problème réel avec son code. ** Il obtient ** l'exception hors de l'index ** à cause de l'accès à 'fib [100]' alors que le dernier élément est 'fib [99]'. –

1
public static int FibNo(int n) { 
    int result = 0; int No = 0; int N1 = 1; 

    if (n< 0) 
    { throw new ArguementException("number must be a positive value"); } 

    if (n <= 1) 
    { result = n; return result; } 

    for(int x=1; x < n; x++) 
    { result = No + N1; No = N1; N1=result; } 

    return result; 

}