сломать запрос IEnumerable <int>, который использует Enumerable.Range - PullRequest
2 голосов
/ 25 апреля 2009

У меня есть следующий запрос 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, поэтому я позволил этому остановиться на этом. В этом случае число было достаточно.

Но это просто закодированное "случайное" число. Если вы посмотрите на код, то обнаружите, что как только значение p == sumofPowers.Sum() истинно, вам больше не нужно выполнять цикл.

Я знаю, yield может делать это в других ситуациях, а break работает в обычных циклах - так что вы можете сделать в этой ситуации?

Ответы [ 3 ]

4 голосов
/ 25 апреля 2009

Вы можете использовать оператор First (), чтобы выйти из игры.

Поскольку LINQ выполняет отложенные вычисления, это будет продолжаться до тех пор, пока вы не достигнете точки, где p == sumofPowers.Sum (), а затем вернете первый элемент. Просто оберните весь запрос в (...). First (); вернуть первое значение.

Кроме того, пока вы не занимаетесь преобразованием в строку, а затем в double, вы можете преобразовать напрямую из int -> double и избежать преобразования строк.

1 голос
/ 17 июля 2011
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();
    }
}
0 голосов
/ 25 апреля 2009

LINQ - это не решение всех проблем. Ваша проблема имеет только диапазон, который определяется ее решением, поэтому с точки зрения «запроса» диапазон отсутствует, что делает его неподходящим для известных операций над множествами, таких как LINQ и стандартных методов расширения IEnumerable. Вы бы сделали лучше (и создали бы более читаемый код), используя оператор yield.

...