Способ выражения простых множителей числа

Моя задача - вернуть простые множители целого числа (n). Мой вопрос в том, как мне выразить это в математическом выражении для кодирования? Я знаю, что простые числа — это числа, которые делятся только на 1 и само на себя, но не знаю, как поместить это в код.

Однако я нашел эту кодировку, которая работает, но я не знаю, почему:

def primes(n):

    primfac = []
    d = 2
    while d*d <= n:
        while (n % d) == 0:
            primfac.append(d)  
            n //= d
        d += 1
    if n > 1:
       primfac.append(n)
    return primfac

Может кто-нибудь объяснить мне, почему эта кодировка работает? Почему d выбрано как 2 для начала вместо 1? Кроме того, почему он возводит в квадрат d и проверяет, равно ли оно n или меньше? и так далее.


person Jessica    schedule 07.03.2016    source источник
comment
1 не является простым числом.   -  person pp_    schedule 07.03.2016
comment
Он просто перебирает все числа, начиная с 2, удаляя множители по мере их нахождения (и добавляя их в список). Они всегда будут простыми, потому что перед тем, как пробовать какое-либо составное число, его делители уже будут удалены из вашего числа.   -  person Tom Karzes    schedule 07.03.2016
comment
Да и начинать с 1 смысла нет. Мало того, что один не является простым, вы просто получите бесконечный список единиц в качестве множителей. Подумай об этом.   -  person Tom Karzes    schedule 07.03.2016
comment
до сих пор не понимаю, почему код добавляет d и почему d возводится в квадрат и проверяется, равно ли оно или меньше n. Также запутался в части n//=d.   -  person Jessica    schedule 07.03.2016
comment
Вкратце, этот код начинается с d = 2, которое является первым простым числом, и обратите внимание, что если d делится на n и d простое, то $d \leq \sqrt{n}$. После проверки того, что d делится на n, этот код уменьшает n до нового числа путем деления n на d до тех пор, пока d не будет делиться на новое число.   -  person GAVD    schedule 07.03.2016
comment
Выразить в математическом выражении для кодирования? Это вопрос о программировании? =) Этот вопрос больше касается алгоритмов и математики, чем обычный вопрос SO. Возможно, вам повезет больше с другими ресурсами, например. en.wikipedia.org/wiki/   -  person rakslice    schedule 07.03.2016
comment
чтобы ответить на ваш первый вопрос, [d | d<-[2..x], rem x d==0, isPrime d] (этот вопрос на Haskell, но на Python он похож); хотя как алгоритм ваш код намного намного эффективнее.   -  person Will Ness    schedule 07.03.2016


Ответы (1)


d Начинается с 2, потому что вы получите бесконечный список 1 в качестве факторов, как упоминает Tom Karzes. Причина, по которой он возводит d в квадрат и проверяет, равно ли оно n, заключается в том, что вам нужно только проверить квадратный корень числа для его множителей, а math.sqrt() требует больших вычислительных ресурсов, чем возведение числа в квадрат. Что он делает, так это проверяет, является ли d коэффициентом n, пока d не достигнет квадратного корня из n. Затем он добавляет d, поскольку было проверено, что это фактор.

Есть ли что-то еще, что вы не понимаете в коде?

person Paul Virally    schedule 07.03.2016
comment
Я хотел поместить это в комментарии, так как не думаю, что это заслуживает полного ответа, но у меня недостаточно репутации...: D Извините, это мой второй ответ на SO :) - person Paul Virally; 07.03.2016
comment
это ответило на все о коде, спасибо! Последний вопрос: это единственный способ выразить/проверить простые множители? Это задание, и хотя я понимаю, как теперь работает код, я не решаюсь просто скопировать этот код, если есть множество других способов сделать это. - person Jessica; 07.03.2016
comment
Есть несколько более сложных алгоритмов, которые имеют дело с простой факторизацией и проверкой того, являются ли числа простыми, и т. д. Однако, насколько мне известно, это самый быстрый способ получить полный список простых делителей n. Эти алгоритмы называются проверками простоты, но они только проверяют, является ли число простым. Возможно, вы сможете изменить один или два, чтобы получить список простых множителей n, но опять же, насколько мне известно, это самый простой и эффективный способ получить простые множители n. - person Paul Virally; 07.03.2016
comment
Вы также можете оптимизировать этот код с тем фактом, что 2 — это единственное четное простое число. Итак, вы начинаете с d=2, затем продолжаете с d=3. После этого вам нужно только проверить другие нечетные числа (5,7,9,11,...). Вы делаете это, увеличивая d на два вместо одного. - person Sci Prog; 07.03.2016