1

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

我的问题是:X 在 SkipWhile 方法调用中设置在哪里?当我在运行时中断代码并单步执行到该点时,我从来没有看到为它设置了一个值。然而,代码将一直有效。我检查了 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;
        }
    }
4

3 回答 3

2

我相信你在谈论lambda 表达式

x => number % x > 0

所有 lambda 表达式都使用 lambda 运算符 =>,读作“goes to”。lambda 运算符的左侧指定输入参数(如果有),右侧保存表达式或语句块。

在 LINQ 表达式中,每个项目在迭代时都会提供给 lambda。在 lambda 的主体中,如果您希望引用该项目,则需要为其命名。在这种情况下,参数最终命名为x

于 2012-05-16T19:08:10.487 回答
2

看起来像这样的表达式:

x => number % x > 0

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

下面是如何将 lambda 表达式编写为函数:

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

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

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

于 2012-05-16T19:09:04.030 回答
0

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

于 2012-05-16T19:07:45.407 回答