Вот самый тупой способ:
def divisorGenerator(n):
for i in xrange(1,n/2+1):
if n%i == 0: yield i
yield n
Результат, который я хотел бы получить, похож на этот, но мне нужен более умный алгоритм (он слишком медленный и тупой :-)
Я могу найти простые множители и их кратность достаточно быстро. У меня есть генератор, который генерирует фактор таким образом:
(фактор1, множественность1)
(фактор2, множественность2)
(фактор3, множественность3)
и так далее ...
т.е. выход
for i in factorGenerator(100):
print i
является:
(2, 2)
(5, 2)
Я не знаю, насколько это полезно для того, что я хочу делать (я закодировал это для других задач), в любом случае мне нужен более умный способ сделать
for i in divisorGen(100):
print i
выведите это:
1
2
4
5
10
20
25
50
100
ОБНОВЛЕНИЕ: Большое спасибо Грегу Хьюджиллу и его "умному способу" :) Расчет всех делителей 100000000 занял 0,01 с его путем против 39, которые этот глупый способ взял на мою машину, очень круто: D
ОБНОВЛЕНИЕ 2: перестаньте говорить, что это дубликат этого сообщения. Чтобы вычислить количество делителей данного числа, не нужно вычислять все делители. Это другая проблема, если вы думаете, что это не так, то поищите "Функция делителя" в Википедии. Прочтите вопросы и ответ перед публикацией, если вы не понимаете, о чем идет речь, просто не добавляйте бесполезные и уже предоставленные ответы.
Ответы:
Учитывая вашу
factorGenerator
функцию, вотdivisorGen
что должно работать:Общая эффективность этого алгоритма будет полностью зависеть от эффективности
factorGenerator
.источник
Чтобы расширить то, что сказал Шими, вы должны запускать свой цикл только от 1 до квадратного корня из n. Затем, чтобы найти пару, выполните
n / i
, и это покроет все проблемное пространство.Как было также отмечено, это NP, или «сложная» проблема. То, как вы выполняете исчерпывающий поиск, примерно так же хорошо, как и для гарантированных ответов. Этот факт используется алгоритмами шифрования и т.п. для их защиты. Если бы кто-то решил эту проблему, большая часть, если не все наши текущие «безопасные» коммуникации были бы небезопасными.
Код Python:
Что должно вывести список вроде:
источник
Хотя для этого уже есть много решений, мне действительно нужно опубликовать это :)
Этот:
Код:
источник
while i*i <= nn
наwhile i <= limit
, гдеlimit = math.sqrt(n)
Думаю, можно остановиться на
math.sqrt(n)
вместо n / 2.Я приведу вам пример, чтобы вы легко его поняли. Теперь
sqrt(28)
это5.29
такceil(5.29)
будет 6. Так что , если я остановлюсь на 6 , то я могу получить все делители. Как?Сначала посмотрите код, а затем посмотрите изображение:
Теперь см. Изображение ниже:
Допустим, я уже добавил
1
в свой список делителей, и я начинаюi=2
такИтак, в конце всех итераций, когда я добавил частное и делитель в свой список, все делители 28 заполнены.
Источник: Как определить делители числа
источник
math.sqrt(n) instead of n/2
обязателен для элегантностиМне нравится решение Грега, но хотелось бы, чтобы оно было больше похоже на питон. Я чувствую, что это будет быстрее и читабельнее; так что после некоторого времени кодирования я вышел с этим.
Первые две функции необходимы для создания декартового произведения списков. И может быть повторно использован всякий раз, когда возникает эта проблема. Кстати, мне пришлось самому программировать это, если кто-нибудь знает стандартное решение этой проблемы, пожалуйста, свяжитесь со мной.
«Factorgenerator» теперь возвращает словарь. Затем словарь передается в «делители», которые используют его для создания сначала списка списков, где каждый список представляет собой список факторов в форме p ^ n с простым p. Затем мы производим декартово произведение этих списков и, наконец, используем решение Грега для создания делителя. Мы их сортируем и возвращаем.
Я тестировал его, и он кажется немного быстрее, чем предыдущая версия. Я тестировал его как часть более крупной программы, поэтому не могу точно сказать, насколько он быстрее.
Пьетро Сперони (расставил все точки над пиетросперони)
PS это первый раз, когда я публикую в stackoverflow. Жду любых отзывов.
источник
Вот умный и быстрый способ сделать это для чисел до и около 10 ** 16 в чистом Python 3.6,
источник
Адаптировано из CodeReview , вот вариант, который работает с
num=1
!источник
NameError: global name 'prime_factors' is not defined
. Ни один из других ответов, ни исходный вопрос не определяют, что это делает.Я просто собираюсь добавить немного переработанную версию Anivarth's (поскольку я считаю, что она самая питоническая) для дальнейшего использования.
источник
Старый вопрос, но вот мое мнение:
Вы можете использовать прокси:
ПРИМЕЧАНИЕ. Для поддерживающих языков это может быть хвостовая рекурсия.
источник
Предполагая, что
factors
функция возвращает множители n (например,factors(60)
возвращает список [2, 2, 3, 5]), вот функция для вычисления делителей n :источник
Вот мое решение. Это кажется глупым, но работает хорошо ... и я пытался найти все правильные делители, поэтому цикл начался с i = 2.
источник
Если вы заботитесь только об использовании списков, и все остальное для вас не имеет значения!
источник
Если на вашем компьютере много памяти, простой простой строки может быть достаточно с numpy:
На моем медленном ПК занимает менее 1 секунды.
источник
Мое решение с помощью функции генератора:
источник
источник
Для меня это отлично работает и тоже чисто (Python 3)
Не очень быстро, но возвращает делители построчно, как вы хотели, также вы можете использовать list.append (n) и list.append (number), если действительно хотите
источник