Fibonacci序列的偶数和

时间:2012-08-08 01:22:36

标签: c# .net fibonacci

我在stackoverflow上遇到了这个问题:

  

“我在Project Euler中遇到了一些问题。   这是问题的问题:   Fibonacci序列中的每个新术语都是通过添加前两个术语生成的。从1和2开始,前10个项将是:1,2,3,5,8,13,21,34,55,89,......查找序列中所有偶数项的总和不超过四百万。“

最重要的答案是这个(在VS2010中我没有为我编译......为什么?):

    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 % 2 == 0))
    {
        result+=i;
    }
    Console.WriteLine(result);

我决定自己尝试一下,然后找到答案并提出这个问题(请告诉我为什么或为什么这不是解决这个问题的好方法或坏方法):

我是在课堂上写的,因为我可以在将来为课堂添加更多内容,而不仅仅是解决单个斐波那契问题。

class Fibonacci
{
    private int prevNum1 = 1;
    private int prevNum2 = 2;
    private int sum = 0;

    public int GetSum(int min, int max)
    {
        prevNum1 = min;
        prevNum2 = prevNum1 + prevNum1;
        if (prevNum1 % 2 == 0)
        {
            sum += prevNum1;
        }
        if (prevNum2 % 2 == 0)
        {
            sum += prevNum2;
        }
        int fNum = 0;
        while (prevNum2 <= max)
        {
            fNum = prevNum1 + prevNum2;
            if (fNum % 2 == 0)
            {
                //is an even number...add to total
                sum += fNum;
            }
            prevNum1 = prevNum2;
            prevNum2 = fNum;

        }

        return sum;
    }

}

        Fibonacci Fib = new Fibonacci();
        int sum = Fib.GetSum(1, 4000000);

        Console.WriteLine("Sum of all even Fibonacci numbers 1-4,000,000 = {0}", sum);

同样,我正在寻找一个答案,为什么这是解决这个问题的好或坏方法。也是为什么第一个解决方案无法编译。我是一名初学者并且正在努力学习。谢谢!

2 个答案:

答案 0 :(得分:3)

有了这个必须编译:

foreach (int i in Fibonacci().TakeWhile(i => i < 4000000).Where(i => i % 2 == 0))
{
    result += i;
}

代码无法编译的问题是错误的lambda表达式,它是:

.Where(i % 2 == 0)

但必须

.Where(i => i % 2 == 0)

答案 1 :(得分:2)

由于以下行,代码无法编译:

foreach (int i in Fibonacci().TakeWhile(i => i<4000000).Where(i % 2 == 0))

首先,。Where()是一种可以通过集合调用的扩展方法(google it)(在本例中类似于IEnumerable of integers)。它返回另一个包含满足某些条件的元素的集合。

注意.Where()的参数是一个产生布尔值的表达式,true或false ..

i % 2 == 0

.Where()不会将bool作为参数,在这种情况下,适当的参数是类型

Func<int,bool>

这基本上意味着一个函数有一个int作为参数并返回bool。您可以非常简单地定义这些

// defines a function taking an int, returning true if that int is even
Func<int,bool> foo = i => i % 2 == 0

所以在这种情况下使用.Where()的正确方法是

foreach (int i in Fibonacci().TakeWhile(i => i<4000000).Where(i => i % 2 == 0))

所以你可以看到.Where()接受我们提供它的函数并将它应用于每个数字,返回一组偶数的数字。

yield关键字还有其他一些神奇之处,请随意谷歌这一点,但它更像是一个高级主题。