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();
}
也许您不想要一个在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
,也许你必须考虑一下b1
、b2
的技巧——这只是因为我不想引入一个伪变量来记住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]);