سؤال

أنا أتدرب على تطبيق وحدة تحكم 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;
    }
}

هل يمكن لأحد أن يقول لي ما الخطأ الذي أفعله هنا؟

هل كانت مفيدة؟

المحلول

وهنا الحل الذي يتفوق على كل ما تبذلونه من!

لماذا تكرار عندما يكون لديك ذكية علماء الرياضيات عمل الحلول ذات الشكل المغلق لك؟:)

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

نصائح أخرى

وهنا حل متعة باستخدام كتلة مكرر لانهائي:

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

وأنا فعلا أحب هذا النوع من تنفيذ فيبوناتشي مقابل الحل عودي التقليد، لأنها تحافظ على العمل المستخدمة لإكمال المدى المتاح لاستكمال المقبل. الحل عودي التقليدي تكرار بعض الأعمال، لأنه يحتاج مكالمتين متكررة كل فصل دراسي.

والمشكلة تكمن في <= البيان التالي:

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

وأكثر لهذه النقطة و=. ليس هناك أكذوبة [100] (C # الصفر التهم) وذلك عند تحقق على ط = 100 تحصل على استثناء.

ويجب أن يكون البيان الصحيح

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

وأو حتى أفضل

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

حسنا، بالنسبة للمبتدئين مجموعة الخاصة بك طويلة فقط 10 وكنت ملئه مع ~ 100 وحدات (خارج المدى استثناء) - ولكن هناك طرق أفضل للقيام بذلك ...

وعلى سبيل المثال، وذلك باستخدام هذا المنصب :

long val = ...
bool isFib = Fibonacci().TakeWhile(x => x <= val).Last() == val;
int[] fib = new int[10];
for (int i = 2; i <= *100*; i++)

أنت الخروج من حدود مجموعة الخاصة بك لحلقة الخاص بك مشروطة كبيرة جدا. ومن شأن اتباع نهج أكثر تقليدية ستكون ملزمة حلقة من حجم مجموعة:

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

وجعل مجموعة الخاص بك أكبر، ولكن كما قال مارك، وهناك طرق أفضل للقيام بذلك، وأنصح لك قضاء بعض الوقت في قراءة مقالة ويكيبيديا على <لأ href = "http://en.wikipedia.org/ ويكي / Fibonacci_number "يختلط =" نوفولو noreferrer "> أرقام فيبوناتشي .

وشيء واحد يمكنك القيام به هو التحقق من الخروج المبكر. منذ كنت في محاولة لتحديد ما إذا كان عدد معين هو في سلسلة فيبوناتشي، يمكنك أن تفعل حدود فحص للخروج في وقت مبكر.

مثال:

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

}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top