Вывести все делители числа вводимого с клавиатуры постарайтесь чтобы было как можно меньше итераций
Делитель — это число, на которое нацело делится делимое. У делимого может быть один или несколько делителей, найти их все можно с помощью простого алгоритма, который без проблем реализуется на Python 3.
Нахождение делителей числа
С практической точки зрения будет полезно, если программа на Python не только будет находить делители числа, искать их сумму, определять минимальный и максимальный, а также простые делители.
Каждая подзадача так или иначе связана с предыдущей, поэтому код последующей программы — это немного модернизированный код предыдущей. Кроме того, весь функционал при необходимости можно объединить в одной программе.
Алгоритм нахождения очень простой. В цикле перебираются значения от делимого минус единица до двух включительно. Если делимое нацело делится на текущее значение, то оно является делителем.Пользователь вводит целое число, делителей которого будет искать программа, тогда код выглядит так:
Например, пользователь ввёл число 625. Программа начинает цикл со значения 624, в цикле проверяется, делится ли нацело 625 на 624, затем цикл переходит на следующую итерацию и работает уже с числом 623 и так до двух. Таким образом, вывод программы будет следующим:
Простые делители числа
Простой делитель — это делитель, который делится только на единицу и самого себя. Для нахождения простых делителей с помощью Python нужно немного модернизировать программу, добавив в неё дополнительный цикл for и переменную счётчик.
Программа построена по следующему алгоритму:
- Обнулить счётчик.
- В цикле искать делители.
- Если найден, искать во вложенном цикле его делители. Это для того, чтобы определить: является ли он простым.
- Если найден, увеличить счётчик.
- Если счётчик равен нулю, то число простое и надо вывести значение делителя в консоль.
- Перейти на следующую итерацию внешнего цикла.
Цикл теперь выглядит так:
Результат работы программы:
Делители расположены в порядке убывания. И если надо вывести только самый большой простой делитель с помощью Python, то можно после того, как выведется первое число, воспользоваться оператором break для выхода из цикла.
Сумма делителей
Для того чтобы найти сумму всех делителей числа с помощью Python, достаточно добавить в начальную программу переменную, к которой в цикле будет прибавляться каждый найденный делитель.
Код программы:
Результат выполнения кода:
Количество делителей
Результаты выполнения программы:
Максимальный и минимальный делитель
Для нахождения минимального и максимального делителя в код на Python нужно добавить две переменные: min_divider и max_divider . В цикле делитель будет сравниваться со значением этих переменных и, если необходимо, записываться в них.
Я могу найти простые множители и их кратности достаточно быстро. У меня есть генератор, который генерирует фактор таким образом:
(factor1, multiplicity1)
(factor2, multiplicity2)
(factor3, multiplicity3)
и так далее.
Я не знаю, насколько это полезно для того, что я хочу сделать (я закодировал его для других проблем), в любом случае я хотел бы более умный способ сделать
обновление: большое спасибо Грег Hewgill и его "умным способом" :) Вычисление всех делителей 100000000 заняло 0.01 s с его пути против 39s, что тупой путь взял на моей машине, очень круто : D
обновление 2: перестаньте говорить, что это дубликат этого поста. Вычисление числа делителей данного числа не требует вычисления всех делителей. Это другая проблема, если вы думаете, что это не так, то ищите "функцию делителя" в Википедии. Прочитайте вопросы и ответ перед публикацией, если вы не понимаете, что это за тема, просто не добавляйте не полезные и уже данные ответы.
учитывая вашу функцию factorGenerator, вот divisorGen, который должен работать:
общая эффективность этого алгоритма будет полностью зависеть от эффективности factorGenerator.
- читабельный
- короче
- автономный, копировать и вставить готов
- быстро (в случаях с большим количеством простых множителей и делителей, > в 10 раз быстрее, чем решение Грега)
- python3, python2 и PyPy совместимый
Я думаю, вы можете остановиться на math.sqrt(n) вместо n / 2.
я приведу вам пример, так что вы можете понять это легко. Теперь sqrt(28) и 5.29 так ceil(5.29) будет 6. Поэтому я, если я остановлюсь на 6, тогда я смогу получить все делители. Как?
сначала смотрите код, а затем смотрите изображение:
теперь смотрите изображение ниже:
допустим, я уже добавил 1 к моему списку делителей, и я начинаю с i=2 так что
Итак, в конце всех итераций, когда я добавил фактор и делитель в свой список, все делители 28 заполняются.
надеюсь, что это помогает. Если у вас есть какие-либо сомнения, не стесняйтесь пинг и я буду рад помочь вам :).
источник: как определить делители числа
радиус круга - и код и изображение
Мне нравится решение Грега, но я хотел бы, чтобы это было больше похоже на python. Я чувствую, что это будет быстрее и читабельнее; поэтому через некоторое время кодирования я вышел с этим.
первые две функции необходимы, чтобы сделать декартово произведение списков. И может быть использован повторно, когда эта проблема возникает. Кстати, я должен был запрограммировать это сам, если кто-нибудь знает стандартное решение этой проблемы, пожалуйста, не стесняйтесь обращаться ко мне.
"Factorgenerator" теперь возвращает словарь. И затем словарь подается в "делители", которые используют его для создания первого списка списков, где каждый список является списком факторов вида p^n с P prime. Затем мы делаем декартово произведение этих списков, и мы, наконец, используем решение Грега для генерации делителя. Мы сортируем их и возвращаем обратно.
Я проверил его, и это, кажется, немного быстрее, чем в предыдущей версии. Я тестировал его как часть более крупной программы, поэтому я не могу сказать, насколько это быстрее хотя.
Пьетро Сперони (pietrosperoni dot it)
С. П. это первый раз, когда я публикую в stackoverflow. Я с нетерпением жду любой обратной связи.
Например, делители числа 24 являются 1 2 3 4 6 8 12 24 ,
- Найти все простые факторы данного числа через это решение .
- Получить все возможные комбинации этих основных факторов.
Тем не менее, это не кажется хорошим.
Решение
Факторы сопряжены. 1 а также 24 , 2 а также 12 , 3 а также 8 , 4 а также 6 ,
Улучшение вашего алгоритма может заключаться в повторении до квадратного корня num вместо всего пути к num , а затем рассчитать парные факторы, используя num / i ,
Другие решения
Вы действительно должны проверять до получения квадратного корня из num как sqrt (num) * sqrt (num) = num:
Что-то на этих линиях:
В настоящее время в науке нет эффективного способа в смысле алгоритмической сложности (алгоритма с полиномиальной сложностью). Так что итерация до получения квадратного корня, как уже было предложено, в основном настолько хороша, насколько это возможно.
Главным образом из-за этого большая часть используемой в настоящее время криптографии основана на предположении, что для вычисления простой факторизации любого заданного целого числа требуется очень много времени.
Первая часть, sieve () используется для поиска простых чисел и помещения их в массив primes []. Перейдите по ссылке, чтобы узнать больше об этом коде (побитовое сито).
Вторая часть primeFactors (x) принимает целое число (x) в качестве входных данных, находит его простые множители и соответствующий показатель степени и помещает их в векторные факторы []. Например, primeFactors (12) будет заполнять факторы [] следующим образом:
как 12 = 2 ^ 2 * 3 ^ 1
Третья часть setDivisors () рекурсивно вызывает себя для вычисления всех делителей x, используя векторные множители [], и помещает их в векторные делители [].
Он может вычислять делители любого числа, которое вписывается в int. И это довольно быстро.
Существует множество хороших решений для нахождения всех основных факторов не слишком большого числа. Я просто хотел отметить, что, как только они у вас есть, не требуется никаких вычислений, чтобы получить все факторы.
Тогда число факторов явно (a+1)(b+1)(c+1). поскольку каждый фактор может равняться нулю до одного раза.
например 12 = 2^2*3^1 так оно и есть 3*2 = 6 факторы. 1,2,3,4,6,12
Первоначально я думал, что вы просто хотели количество различных факторов. Но та же логика применима. Вы просто перебираете набор чисел, соответствующих возможным комбинациям показателей.
Если дано натуральное число n, выведите все его различные делители.
Примеры :
Обратите внимание, что эта проблема отличается от поиска всех основных факторов .
Наивным решением было бы перебрать все числа от 1 до n, проверить, делит ли это число n и распечатать его. Ниже программа для того же:
// функция для печати делителей
void printDivisors( int n)
/ * Программа драйвера для проверки вышеуказанной функции * /
// Java реализация метода Naive для печати всех
// делители
// метод для печати делителей
static void printDivisors( int n)
for ( int i= 1 ;i<=n;i++)
System.out.printf( "%d " ,i);
public static void main(String args[])
// метод для печати делителей
static void printDivisors( int n)
for ( int i = 1; i <= n; i++)
public static void Main()
Console.Write( "The divisors of" ,
// Этот код предоставлен нитин митталь.
<?php
// PHP реализация Naive
// метод для печати всех делителей
// функция для печати делителей
function printDivisors( $n )
for ( $i = 1; $i <= $n ; $i ++)
// Этот код предоставлен ajit
?>
Выход :
Сложность времени: O (n)
Вспомогательное пространство: O (1)
Можем ли мы улучшить вышеуказанное решение?
Если мы посмотрим внимательно, все делители присутствуют в парах. Например, если n = 100, то различные пары делителей: (1100), (2,50), (4,25), (5,20), (10,10)
Используя этот факт, мы могли бы значительно ускорить нашу программу.
Мы, однако, должны быть осторожны, если есть два равных делителя, как в случае (10, 10). В таком случае мы напечатали бы только один из них.
Ниже приведена реализация того же:
// Функция для печати делителей
void printDivisors( int n)
// Обратите внимание, что этот цикл работает до квадратного корня
for ( int i=1; i<= sqrt (n); i++)
// Если делители равны, вывести только один
else // В противном случае выведите оба
printf ( "%d %d " , i, n/i);
/ * Программа драйвера для проверки вышеуказанной функции * /
// Лучшее (чем наивное) решение, чтобы найти все делители
// метод для печати делителей
static void printDivisors( int n)
// Обратите внимание, что этот цикл работает до квадратного корня
for ( int i= 1 ; i<=Math.sqrt(n); i++)
// Если делители равны, вывести только один
System.out.printf( "%d " , i);
else // В противном случае выведите оба
System.out.printf( "%d %d " , i, n/i);
public static void main(String args[])
while i < = math.sqrt(n):
// Лучшее (чем наивное) решение
// найти все делители
// метод для печати делителей
static void printDivisors( int n)
// Обратите внимание, что этот цикл выполняется
// до квадратного корня
for ( int i = 1; i <= Math.Sqrt(n);
// Если делители равны,
// распечатать только один
// В противном случае выведите оба
public static void Main()
Console.Write( "The divisors of "
// Этот код предоставлен Smitha
<?php
// Лучшее (чем наивное) решение
// найти все делители
// Функция для печати делителей
function printDivisors( $n )
// Обратите внимание, что этот цикл
// работает до квадратного корня
for ( $i = 1; $i <= sqrt( $n ); $i ++)
// Если делители равны,
// распечатать только один
// В противном случае выведите оба
echo $i , " " , $n / $i , " " ;
// Этот код предоставлен anuj_67.
Выход :
Сложность времени: O (sqrt (n))
Вспомогательное пространство: O (1)
Однако, есть еще небольшая проблема в решении, вы можете догадаться?
Да! результат не в том порядке, который мы получили, используя метод грубой силы. Пожалуйста, обратитесь к ниже для решения времени O (sqrt (n)), которое печатает делители в отсортированном порядке.
Эта статья предоставлена Ашутошем Кумаром . Пожалуйста, напишите комментарии, если вы обнаружите что-то неправильное, или вы хотите поделиться дополнительной информацией по обсуждаемой теме
Читайте также: