2

我有以下 IEnumerable LINQ 查询:

var query = from p in Enumerable.Range(2, 1000000)
let sumofPowers = from ch in p.ToString()
                  let sumOfPowers = Math.Pow(Convert.ToDouble(ch.ToString()), 5)
                  select sumOfPowers
where p == sumofPowers.Sum()
select p;

它找到所有可以写为数字的五次方之和的数字的总和。这是欧拉计划问题 30

它可以正常工作。我知道这是挑剔的,但范围让我很恼火。我基本上已经猜到它在 1,000,000 处找到了正确的结果,所以我让它停在那里。在这种情况下,数量就足够了。

但它只是一个硬编码的“随机”数字。如果您查看代码,您会发现只要 wherep == sumofPowers.Sum()为真,您就不需要再运行循环了。

我知道yield在其他情况下可以做到这一点并break在正常循环中工作 - 那么在这种情况下你可以做些什么吗?

4

3 回答 3

4

您可以使用 First() 运算符进行突破。

由于 LINQ 执行延迟计算,因此这将一直持续到您到达 p == sumofPowers.Sum() 的点,然后返回第一个元素。只需将整个查询包装在 (...).First(); 返回第一个值。

此外,当您使用它时,无需转换为字符串然后再转换为双精度 - 您可以直接从 int -> double 进行转换,并避免字符串转换。

于 2009-04-25T18:33:27.367 回答
1
class Program
{
    static void Main(string[] args)            
    {
        ulong sum, gh = 0;

        for (ulong i = 2; i <= 355000; i++)
        {
            string s = Convert.ToString(i);
            sum = 0;
            int ddd = s.Length;
            for (int j = 0; j < ddd; j++)
            {
                //sum +=(int)Math.Pow(Convert.ToInt32(s[j]), 4);
                ulong g = Convert.ToUInt64(Convert.ToString(s[j]));
                sum = sum + (ulong)Math.Pow(g, 5);
            }
            // Console.WriteLine(sum);
            if (sum == i)
            {
                gh += i;
            }
        }
        Console.WriteLine(gh);

        Console.ReadKey();
    }
}
于 2011-07-17T18:52:34.933 回答
0

LINQ 并不是所有问题的解决方案。您的问题只有一个由其解决方案定义的范围,因此从“查询”的角度来看,没有范围,这不适合已知的集合操作,如 LINQ 和标准 IEnumerable 扩展方法。使用 yield 语句会做得更好(并生成更易读的代码)。

于 2009-04-25T18:32:47.587 回答