我有以下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;
它找到所有数字的总和,可以写成数字的五次幂之和。这是项目欧拉Problem 30
它可以正常工作。我知道这是挑剔,但范围让我烦恼。 我基本上已经猜到它已经找到了1,000,000的正确结果,所以我让它停在那里。在这种情况下,数量就足够了。
但它只是一个硬编码的“随机”数字。
如果您查看代码,您会发现只要p == sumofPowers.Sum()
为真,就不再需要再次运行循环了。
我知道yield
可以在其他情况下执行此操作,而break
可以在正常循环中运行 - 那么在这种情况下你能做些什么吗?
答案 0 :(得分:4)
您可以使用First()运算符来突破。
由于LINQ确实延迟计算,因此直到达到p == sumofPowers.Sum()的点,然后返回第一个元素。只需将整个查询包装在(...)中.First();返回第一个值。
此外,当你在它时,没有必要转换为字符串然后转换为双 - 你可以直接从int转换 - >加倍,避免字符串转换。
答案 1 :(得分: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();
}
}
答案 2 :(得分:0)
LINQ不是解决所有问题的方法。您的问题只有一个由其解决方案定义的范围,因此从“查询”的角度来看,没有范围,这使得它不适用于已知的集合操作,如LINQ和标准的IEnumerable扩展方法。使用yield语句可以做得更好(并生成更易读的代码)。