[英]Finding Fibonacci sequence in C#. [Project Euler Exercise]
我在Project Euler中遇到了这个问题。
这是问题的问题:
Fibonacci序列中的每个新术语都是通过添加前两个术语生成的。 从1和2开始,前10个项将是:1,2,3,5,8,13,21,34,55,89,......查找序列中所有偶数项的总和不超过四百万。
到目前为止我的代码: 编辑新代码仍然无法正常工作。
static void Main(string[] args)
{
int a = 1;
int b = 2;
int Container = 0;
int Sum = 0;
while (b < 4000000)
{
if (a % 2 == 0)
{
Container += a;
}
Sum = a + b;
a = b;
b = Sum;
}
Container += b;
Console.WriteLine(Container.ToString());
Console.ReadLine();
}
C#中一个有趣的功能是“yield”关键字,这对于这类事情非常有用:
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;
}
}
long result=0;
foreach (int i in Fibonacci().TakeWhile(i => i<4000000).Where(i => i % 2 == 0))
{
result+=i;
}
Console.WriteLine(result);
“传统的”递归Fibonacci实现在这里是有问题的,因为它抛弃了在上一个请求的期限内完成的所有工作。 你必须在一个循环中反复调用这样的函数,这会复制很多工作,或者你可以从该实现开始并在递归函数中添加一个参数来构建所需的和结果作为最终的斐波纳契项计算。 我更喜欢这个,因为它仍然是核心的通用fibonacci序列,而不是你必须重写或专门化的。
另一种方法是在传统实现中使用事件(委托)来在每个术语完成时调用单独的方法,但是因为我仍然更喜欢迭代器方法,所以我将留下委托选项作为读者的练习。
您的问题不是您的代码包含错误; 您的问题是您的代码包含错误,而您不知道如何找到它。 首先解决第二个问题,然后当你遇到错误时你不需要问我们,你可以自己找到它。
学习如何发现错误很难,需要大量的练习。 这是我如何处理这个问题。
我首先将问题简化为我自己可以做的事情。 而不是“什么是不超过四百万的偶数纤维数的总和?” 我会问“什么是不超过40的偶数纤维数的总和?” 这很容易手工解决 - 2 + 8 + 34 = 44。
现在在调试器中运行程序,逐步执行每一行,并查看出错的地方。 你的程序实际上是2,8和34吗? 如果是这样,它会得到正确的结果吗?
int sum = 2;
for(int f1 = 1, f2 = 2, f3 = 0; !((f3 = (f1 + f2)) > 4000000); f1 = f2, f2 = f3)
sum += f3 * (~f3 & 1);
你在每次迭代时检查a
和b
。 所以这意味着你几乎可以重复所有事情。
编辑:
好的,我看到你的更新。 这是非常基本的调试,你应该学会自己尝试。 想想当循环条件停止为真时a
和b
的值是什么。
我想问的问题是,你要将所有偶数加在一起,而序列中的数字不超过四百万,这意味着你要加3,999,992。
乔尔,我写了一些类似的代码; 无论如何我发布了它:
static IEnumerable<int> Fibonacci(int maximum)
{
int auxiliar = 0;
int previous = 0;
int current = 1;
while (current < maximum)
{
auxiliar = previous;
previous = current;
current = auxiliar + current;
yield return current;
}
}
Console.WriteLine(Fibonacci(4000000).Where(number => number % 2 == 0).Sum());
这是查找Fibonnaci数字的好方法。
IEnumerable<BigInteger> Fibs()
{
for(BigInteger a = 0,b = 1;;b = a + (a = b))
yield return b;
}
// count(user input) of Fibonacci numbers
int[] array = new int[20];
array[0] = 0;
array[1] = 1;
Console.WriteLine(array[0] + "\n" + array[1]);
for (int i = 2; i < 20; i++)
{
array[i] = array[i - 1] + array[i - 2];
Console.WriteLine(array[i]);
}
更棘手的方式:
//1: Allow declaring of recursive functions
private delegate Func<T, R> FuncRec<T, R>(FuncRec<T, R> f);
static Func<T, R> RecFunction<T, R>(Func<Func<T, R>, Func<T, R>> f)
{
FuncRec<T, R> funcRec = r => t => f(r(r))(t);
return funcRec(funcRec);
}
//Define the factorial function
public static readonly Func<ulong, ulong> Fibonacci
= RecFunction<UInt64, UInt64>(fib => n =>
(n == 1 || n == 0)
? n
: fib(n - 1) + fib(n - 2));
//Make a "continous" version
static IEnumerable<ulong> ContinousFibonacci()
{
ulong count = 0;
while(true)
{
ulong n = Fibonacci(count);
count++;
yield return n;
}
}
//Linq result
static void Main(string[] args)
{
ulong result = ContinousFibonacci()
.TakeWhile(r => r < 4000000)
.Where(IsEven)
.Aggregate<ulong, ulong>(0,(current, s) => (s + current));
Console.WriteLine(result);
Console.ReadLine();
}
///允许一个人创建递归函数的Functional-Style方法由Bart De Smet制作。 见http://bartdesmet.net/blogs/bart/archive/2009/11/08/jumping-the-trampoline-in-c-stack-friendly-recursion.aspx
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.