2009-07-02 81 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; 

}