无法弄清楚值的设置位置

时间:2012-05-16 19:05:24

标签: c#

我正在研究一些Project Euler问题,需要一些帮助来理解我找到的解决方案。

我的问题是:在SkipWhile方法调用中设置X的位置是什么?当我在运行时中断代码并逐步执行到那一点时,我从未看到为其设置的值。然而,代码将一直有效。我检查了SkipWhile的定义,也许我只是不明白在调用中传递的参数如何满足3参数方法定义。 Math.Pow也是一样 - X在哪里设置!?

public long FindGreatestPrimeFactor(long factorGreaterThan, long number)
    {
        long upperBound = (long)Math.Ceiling(Math.Sqrt(number));

        // find next factor of number
        long nextFactor = Range(factorGreaterThan + 1, upperBound)
             .SkipWhile(x => number % x > 0).FirstOrDefault();

        // if no other factor was found, then the number must be prime
        if (nextFactor == 0)
        {
            return number;
        }
        else
        {
            // find the multiplicity of the factor
            long multiplicity = Enumerable.Range(1, Int32.MaxValue)
                 .TakeWhile(x => number % (long)Math.Pow(nextFactor, x) == 0)
                 .Last();

            long quotient = number / (long)Math.Pow(nextFactor, multiplicity);

            if (quotient == 1)
            {
                return nextFactor;
            }
            else
            {
                return FindGreatestPrimeFactor(nextFactor, quotient);
            }
        }
    }

    private IEnumerable<long> Range(long first, long last)
    {
        for (long i = first; i <= last; i++)
        {
            yield return i;
        }
    }

3 个答案:

答案 0 :(得分:2)

我相信你在谈论lambda expression

x => number % x > 0
  

所有lambda表达式都使用lambda operator =&gt;,它被读作“转到”。 lambda运算符的左侧指定输入参数(如果有),右侧包含表达式或语句块。

在LINQ表达式中,每个项目在迭代时都提供给lambda。在lambda的主体中,如果你想引用该项,你需要给它一个名字。在这种情况下,参数最终名为x

答案 1 :(得分:2)

表达式如下:

x => number % x > 0

被称为lambda expressions。它们实际上是函数,x是参数。 SkipWhile接受一个函数,然后使用不同的参数值执行它。

以下是lambda表达式如何写成函数:

bool Foobar(long x)
{
    return number % x > 0;
}

SkipWhile中,我相信调用该函数时x是列表中的第一项。如果为true,则使用列表中的第二项再次调用该函数,依此类推,直到函数返回false。

在这种情况下,SkipWhile要求的函数会将列表中类型的值转换为bool。 Lambda表达式是表达这一点的简洁方法。

答案 2 :(得分:0)

SkipWhile正在从x方法中检索其输入值(Range),后者又会将数字从factorGreaterThan + 1返回到upperBound。不知道为什么作者决定为此编写一个方法,因为它是使用Enumerable.Range方法构建的。