Существует ли эффективный алгоритм для перечисления множителей числа n в порядке возрастания, без сортировки? Под "эффективным" я имею в виду:
-
Алгоритм избегает поиска грубой силы для делителей, начиная с факторизации первичной мощности n.
-
Сложность алгоритма выполнения - O (d log₂ d) или лучше, где d - количество делителей n.
-
Пространственная сложность алгоритма O (d).
-
Алгоритм избегает операции сортировки. То есть факторы производятся по порядку, а не выходят из строя и сортируются впоследствии. Хотя перечисление с использованием простого рекурсивного подхода, а затем сортировка - O (d log₂ d), для всех обращений к памяти, участвующих в сортировке, существует очень уродливая стоимость.
Тривиальный пример: n = 360 = 2 ³ × 3² × 5, который имеет d = 24 фактора: {1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 18, 20, 24, 30, 36, 40, 45, 60, 72, 90, 120, 180, 360}.
Более серьезным примером является n = 278282512406132373381723386382308832000 = 2 × × 3 × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × × 71 × 73 × 79, что имеет d = 318504960 факторов (очевидно, слишком много, чтобы перечислять здесь!). Между прочим, это число имеет наибольшее число факторов любого числа до 2 ^ 128.
Я мог бы поклясться, что несколько месяцев назад я увидел описание такого алгоритма с образцом кода, но теперь я не могу найти его нигде. Он использовал какой-то волшебный трюк для поддержания списка индексов предшественников в выходном списке для каждого основного фактора. (Обновление: я запутался в генерации факторов с номерами Хэмминга, которые работают аналогично.)
Update
В итоге я использовал решение, которое является O (d) во время выполнения, имеет чрезвычайно низкую накладную память, создавая вывод O (d) на месте и значительно быстрее, чем любой другой метод, о котором я знаю. Я отправил это решение в качестве ответа, с исходным кодом C. Это сильно оптимизированная, упрощенная версия красивого алгоритма, представленного здесь в Haskell другим автором, Will Ness. Я выбрал "Ответ" в качестве принятого ответа, поскольку он предоставил очень элегантное решение, соответствующее всем требованиям, как изначально указано.