2

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

ここで何が間違っているのか誰にも教えてもらえますか?

4

7 に答える 7

19

無限反復子ブロックを使用した楽しいソリューションを次に示します。

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

私は実際、この種のフィボナッチの実装と従来の再帰的なソリューションの比較が本当に気に入っています。従来の再帰的ソリューションでは、項ごとに 2 回の再帰呼び出しが必要なため、一部の作業が重複します。

于 2009-07-02T18:46:53.843 に答える
10

問題は<=次のステートメントにあります。

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++)
于 2009-07-02T18:55:03.483 に答える
6

そして、ここにあなたのすべてを打ち負かす解決策があります!

なぜなら、スマートな数学者が閉じた形式のソリューションを提供しているのに、なぜ反復する必要があるのでしょうか? :)

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;
}
于 2011-11-26T20:03:29.930 に答える
5

まず、配列の長さはわずか 10 で、最大 100 個の項目 (範囲外の例外) で満たされていますが、これを行うためのより良い方法があります...

たとえば、次の投稿を使用します

long val = ...
bool isFib = Fibonacci().TakeWhile(x => x <= val).Last() == val;
于 2009-07-02T18:42:59.293 に答える
2
int[] fib = new int[10];
for (int i = 2; i <= *100*; i++)

ループ条件が大きすぎるため、配列の境界を超えています。より伝統的なアプローチは、配列のサイズでループをバインドすることです。

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

配列を大きくしますが、Marc が言ったように、これを行うためのより良い方法があります。フィボナッチ数に関するウィキペディアの記事を読む時間を費やすことをお勧めします。

于 2009-07-02T18:46:50.520 に答える
2

できることの 1 つは、早期終了を確認することです。特定の数値がフィボナッチ数列にあるかどうかを判断しようとしているので、境界チェックを行って早期に終了できます。

例:

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;
}
于 2009-07-02T18:44:02.740 に答える
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;

}
于 2011-11-26T19:05:37.387 に答える