Найдите число делителей числа, заданного массивом простых факторов, используя LINQ. - PullRequest
1 голос
/ 05 января 2010

Учитывая массив простых факторов натурального числа, как я могу найти общее число делителей, используя LINQ на исходном массиве? Я уже выяснил большую часть этой проблемы, но я ' У меня проблемы с моим заявлением LINQ.


Математический фон:

Первичными множителями числа являются простые целые числа, которые делятся равномерно на число без остатка. например Основными факторами 60 являются 2,2,3,5.

Все делители числа - это целые числа (простые или иные), которые делятся равномерно на число без остатка. Делителями 60 являются 1,2,3,4,5,6,10,12,15,20,30,60.

Мне интересно узнать общее число делителей. Общее количество делителей на 60 составляет 12.

Давайте выразим простую факторизацию, используя показатели степени:

60 = 2^2 * 3^1 * 5*1

Чтобы найти общее число делителей с учетом простой факторизации числа, все, что нам нужно сделать, это добавить 1 к каждому показателю степени и затем умножить эти числа вместе, например:

(2 + 1) * (1 + 1) * (1 + 1) = 12;

Вот как вы находите число делителей с учетом простой факторизации числа.

Код, который у меня есть:

У меня уже есть хороший код, чтобы получить основные множители числа, поэтому меня это не беспокоит. Используя LINQ , я хочу выяснить, каково общее число делителей. Я мог бы использовать несколько циклов, но я пытаюсь использовать LINQ (если это возможно).

Я собираюсь:

  • Используйте Distinct(), чтобы найти уникальные значения в массиве.
  • Используйте Count(), чтобы узнать, сколько раз встречаются уникальные значения (это равно показателю степени).
  • Используйте функцию Aggregate(), чтобы умножить значения вместе.

Вот код, который у меня есть:

class Program
{
    static void Main(string[] args)
    {
        var primeFactors = new int[] { 2, 2, 3, 5 };
        Console.WriteLine(primeFactors.Distinct().PrintList("", ", "));
            //Prints: 2, 3, 5
        Console.WriteLine("[2]:{0} [3]:{1} [5]:{2}"
            , primeFactors.Count(x => x == 2)
            , primeFactors.Count(x => x == 3)
            , primeFactors.Count(x => x == 5)
            );
            //Prints: [2]:2 [3]:1 [5]:1

\\THIS IS WHERE I HAVE TROUBLE:

        Console.WriteLine(primeFactors.Distinct().Aggregate((total,next) =>  
            (primeFactors.Count(x => x ==next) + 1)* total));
            //Prints: 8


        Console.ReadLine();
    }
}

В частности , у меня проблемы с этой частью кода:

primeFactors.Distinct().Aggregate((total,next) =>  
    (primeFactors.Count(x => x ==next) + 1)* total)

Поскольку числа в моем массиве хранятся не в виде x^n, а в виде n экземпляров x в массиве, я думаю использовать Count(), чтобы найти, что n должно быть в отдельном массиве x. Функция Aggregate предназначена для итерации каждого отдельного элемента в массиве, поиска его Count + 1, а затем умножения его на сумму. Предполагается, что лямбда-выражение в Count использует каждое отдельное число в качестве параметра (next).

Приведенный выше код должен возвращать 12, но вместо этого он возвращает 8. У меня проблема с "переходом" через LINQ в режиме отладки, и я не могу понять, как мне лучше написать это.

Почему эта часть моего кода не возвращает правильное число делителей, как я ожидаю? Есть ли другой (лучший) способ выразить это с помощью LINQ?

Ответы [ 2 ]

4 голосов
/ 05 января 2010

Попробуйте это:

int[] factors = new int[] { 2, 2, 3, 5 };
var q = from o in factors
        group o by o into g
        select g.Count() + 1;
var r = q.Aggregate((x, y) => x * y);

Конкретная проблема с вашим предложенным запросом состоит в том, что ваш агрегатный вызов не может сосчитать самый первый элемент (не говоря уже о том, что счет не увеличивается на 1). Что он ошибочно делает, так это берёт первый фактор и умножает его значение вместо его числа + 1 на следующий.

2 голосов
/ 05 января 2010

Если я понимаю, что вы хотите сделать, вы можете вместо этого использовать GroupBy().

var primeFactors = new int[]{ 2, 2, 3, 5 };
var numFacs = primeFactors.GroupBy(f => f, f => f, (g, s) => s.Count() + 1)
                          .Aggregate(1, (x, y) => x * y);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...