c#中的Fibonnachi序列

本文关键字:序列 Fibonnachi 中的 | 更新日期: 2023-09-27 18:26:11

我目前正试图制作一个程序,打印fibonnachi序列的前50项。Fibonacci序列就这样。0,1,1,2,3,5,8,13第N项是前两项的总和。所以在上面的例子中,下一个项将是21,因为它将是前两个项加在一起(8+13)。

我的代码目前没有显示这一点,有人能帮我理解为什么吗?

static void Main(string[] args)
    {
        int[]   fibonnachi  = new int[50];
        fibonnachi[0] = 0;
        fibonnachi[1] = 1;
        int fib2ago = 0;
        int fib1ago = 1;
        for (int counter = 2; counter < 51; counter++)
        {
            fibonnachi[counter] = fibonnachi[fib2ago] + fibonnachi[fib1ago];
            Console.Write(fibonnachi[counter] + " ,");
            fib2ago++;
            fib1ago++;
        }
        Console.ReadLine();
    }

c#中的Fibonnachi序列

也许您不想要一个在maxInt处出现溢出的版本,该版本通过在同一函数或某些使用预先确定尺寸的阵列,以占用内存;)

因此,这里有一个有趣的小版本,产生一个中缀序列:

    public static IEnumerable<System.Numerics.BigInteger> Fibonacci()
    {
        System.Numerics.BigInteger current = 0, next = 1;
        while (true) 
        {
            yield return current;
            next = current + next;
            current = next - current; // isn't mutation ugly to read?
        }
    }

你可以这样使用它:

    foreach (var i in Fibonacci().Take(10)) 
    {
        Console.Write("{0} ,", i);
    }
    > 0 ,1 ,1 ,2 ,3 ,5 ,8 ,13 ,21 ,34 ,

注意你可能会让它引用Sytem.Numerics作为BigInteger,也许你必须考虑一下b1b2技巧——这只是因为我不想引入一个伪变量来记住b2来更新b1;)

无耻的广告:

当然,您可以使用递归以一种可读性更强的方式来做到这一点:

public static IEnumerable<System.Numerics.BigInteger> 
    Fibonacci(System.Numerics.BigInteger current,
              System.Numerics.BigInteger next)
{
    yield return current;
    foreach(var n in Fibonacci(next, current+next))
        yield return n;
}

在C#中,这可能会在一段时间后破坏你的内存(我真的不知道编译器是如何处理递归循环的),但这在F#中要自然得多:

let fibonacci =
    let rec create current next =
        seq {
            yield current
            yield! create next (current + next)
        }
    create 0I 1I

或者更惯用的

let fibonacci =
    (0I, 1I)
    |> Seq.unfold (fun (current, next) -> 
        Some (current, (next, current + next)) )

如果你想看到真正好的东西,看看这个:

Fibonacci序列-HaskellWiki:)

代码中的问题是:

  • 您正在循环到50,但数组中的最高索引是49
  • 您在循环中增加了两次counter
  • 循环中不显示前两个数字,因此必须先显示

更新代码:

int[] fibonnachi = new int[50];
fibonnachi[0] = 0;
fibonnachi[1] = 1;
int fib2ago = 0;
int fib1ago = 1;
Console.Write(fibonnachi[0] + " ,");
Console.Write(fibonnachi[1] + " ,");
for (int counter = 2; counter < 50; counter++) {
  fibonnachi[counter] = fibonnachi[fib2ago] + fibonnachi[fib1ago];
  Console.Write(fibonnachi[counter] + " ,");
  fib2ago++;
  fib1ago++;
}

稍微清理一下代码,您可以只使用一个计数器,并通过检查何时开始计算新值来将前两项合并到循环中:

int[] fibonnachi = new int[50];
fibonnachi[0] = 0;
fibonnachi[1] = 1;
for (int counter = 0; counter < 50; counter++) {
  if (counter >= 2) {
    fibonnachi[counter] = fibonnachi[counter - 2] + fibonnachi[counter - 1];
  }
  Console.Write(fibonnachi[counter] + " ,");
}

总体上更好的方法是:

    for (int i = 0; i < 51; i++)
    {
        fibonnachi[i+2] = fibonnachi[i] + fibonnachi[i+1];
        Console.Write(fibonnachi[i] + " ,");
    }

这里说的都是

static void Main(string[] args)
{
    Console.WriteLine("Please enter a number");
    int number = Convert.ToInt32(Console.ReadLine());
    Fibonacci(0, 1, 1, number);
}   
public static void Fibonacci(int a, int b, int counter, int number)
{
    Console.WriteLine(a);
    if (counter < number) Fibonacci(b, a+b, counter+1, number);
}

使用以下代码:

回顾:

      public static int CalculateFibonacci(int n)
       {
          if(n == 0 || n == 1)
           return n;
          else
          return ( CalculateFibonacci(n-1) + CalculateFibonacci(n-2) );
        }

非递归:

int a = 0;
int b = 1;
int c = 1;
for (int i = 0; i < n; i++)
{
    c = b + a;
    a = b;
    b = c;
}
return c;

在循环开始之前,您需要手动打印前两个数字。

                 Console.WriteLine(fibonnachi[0]);
                 Console.WriteLine(fibonnachi[1]);