2009-07-02 79 views
2

我正在練習一個C#控制檯應用程序,我試圖獲取函數來驗證數字是否出現在斐波那契數列中,但是我收到錯誤。C#斐波那契函數返回錯誤

我所做的是:

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

可有人告訴我,我究竟做錯了什麼?

+1

定義「錯誤」... – 2009-07-02 18:48:03

+0

您的意思是#DEFINE錯誤? – Jonathan 2009-07-02 18:52:54

+2

只是好奇,但你爲什麼要返回一個int而不是bool? – Joel 2009-07-02 18:53:25

回答

5

這裏是擊敗了所有你的解決方案!

因爲,爲什麼迭代,當你有智能數學家封閉形式的解決方案適合你?:)

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

嗯,首先你的陣列只有10長,你用〜100個項目(超出範圍的異常)加油吧 - 但也有更好的方法來做到這一點...

爲例如,使用this post

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

你可以做的一件事是檢查提前退出。既然你試圖確定一個給定的數字是否在斐波那契數列中,你可以做邊界檢查以儘早退出。

例子:

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; 
} 
2
int[] fib = new int[10]; 
for (int i = 2; i <= *100*; i++) 

你要你的數組的邊界,因爲你的循環條件是太大。更傳統的方法是綁定的循環由數組的大小:

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

,使你的陣列大,但正如馬克說,有更好的方法來做到這一點,我建議你花一些時間閱讀維基百科文章Fibonacci numbers

18

下面是使用無限迭代器塊一個有趣的解決方案:

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

其實我真的很喜歡這樣的斐波那契實現VS傳統遞歸解決方案,因爲它使用來完成提供一個長期的工作完成下一個。傳統的遞歸解決方案重複了一些工作,因爲每個術語需要兩次遞歸調用。

9

問題在於< =下面的語句:

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

多給點了=。沒有fib [100](C#零計數),所以當你檢查i = 100時,你會得到一個異常。

正確的說法應該是

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

甚至更​​好

for (int i = 2; i < fib.Length; i++) 
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; 

}