2

私はここスタックオーバーフローでこの問題に遭遇しました:

「プロジェクトオイラーでこの問題に問題があります。質問の内容は次のとおりです。フィボナッチ数列の新しい用語は、前の2つの用語を追加して生成されます。1と2から始めると、最初の10の用語は次のようになります。 1、2、3、5、8、13、21、34、55、89、...400万を超えないシーケンス内のすべての偶数値の項の合計を求めます。」

一番の答えはこれでした(これは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);

繰り返しになりますが、これがこの問題を解決するための良い方法または悪い方法である理由についての答えを探しています。また、最初のソリューションがコンパイルされない理由もあります。私は初心者のプログラマーで、学ぼうとしています。ありがとう!

4

2 に答える 2

3

これでコンパイルする必要があります:

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

コードがコンパイルされなかった理由は、ラムダ式が間違っていたためです。

.Where(i % 2 == 0)

しかし、

.Where(i => i % 2 == 0)
于 2012-08-08T01:29:12.493 に答える
2

次の行のため、コードはコンパイルされません。

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

まず、.Where()は、コレクション(この例の整数のIEnumerableなど)に対して呼び出すことができる拡張メソッド(google it)です。ある条件を満たす要素を含む別のコレクションを返します。

.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()は、指定された関数を受け取り、それを各数値に適用して、偶数の数値のコレクションを返すことがわかります。

イールドキーワードで起こっている他の魔法があります、これをグーグルしてください、しかしそれはより高度なトピックです。

于 2012-08-08T01:38:48.383 に答える