web-dev-qa-db-fra.com

Factorisation première - liste

J'essaie d'implémenter une fonction primeFac() qui prend en entrée un entier positif n et renvoie une liste contenant tous les nombres de la factorisation de n.

J'ai atteint ce stade, mais je pense qu'il serait préférable d'utiliser la récursion ici, sans savoir comment créer un code récursif ici, quel serait le scénario de base? commencer avec.

Mon code:

def primes(n):
    primfac = []
    d = 2
    while (n > 1):
         if n%d==0:
             primfac.append(d)
    # how do I continue from here... ?
22
Snarre

Une division d'essai simple:

def primes(n):
    primfac = []
    d = 2
    while d*d <= n:
        while (n % d) == 0:
            primfac.append(d)  # supposing you want multiple factors repeated
            n //= d
        d += 1
    if n > 1:
       primfac.append(n)
    return primfac

avec O(sqrt(n)) complexité (pire des cas). Vous pouvez facilement l’améliorer en utilisant le boîtier spécial 2 et en bouclant uniquement sur d impair (ou en utilisant plus de diviseurs spéciaux plus petits et bouclant sur moins de diviseurs possibles).

41
Daniel Fischer

Il s’agit d’une solution basée sur la compréhension, c’est peut-être ce qui se rapproche le plus d’une solution récursive en Python tout en pouvant être utilisée pour les grands nombres.

Vous pouvez obtenir les diviseurs appropriés avec une seule ligne:

divisors = [ d for d in xrange(2,int(math.sqrt(n))) if n % d == 0 ]

alors nous pouvons tester un nombre dans les diviseurs comme premier:

def isprime(d): return all( d % od != 0 for od in divisors if od != d )

qui teste qu'aucun autre diviseur divise d.

Ensuite, nous pouvons filtrer les diviseurs principaux:

prime_divisors = [ d for d in divisors if isprime(d) ]

Bien entendu, il peut être combiné dans une seule fonction:

def primes(n):
    divisors = [ d for d in range(2,n//2+1) if n % d == 0 ]
    return [ d for d in divisors if \
             all( d % od != 0 for od in divisors if od != d ) ]

Ici, le\est là pour rompre la ligne sans jouer avec l'indentation Python.

13
deufeufeu

Le module primefac fait des factorisations avec toutes les techniques sophistiquées que les mathématiciens ont développées au cours des siècles:

#!python

import primefac
import sys

n = int( sys.argv[1] )
factors = list( primefac.primefac(n) )
print '\n'.join(map(str, factors))
10
brian d foy

Voici ma version de la factorisation par division d'essai, qui intègre l'optimisation de la division par deux et les nombres entiers impairs proposés par Daniel Fischer:

def factors(n):
    f, fs = 3, []
    while n % 2 == 0:
        fs.append(2)
        n /= 2
    while f * f <= n:
        while n % f == 0:
            fs.append(f)
            n /= f
        f += 2
    if n > 1: fs.append(n)
    return fs

Une amélioration de la division d’essai par deux et des nombres impairs est la factorisation roue, qui utilise un ensemble cyclique d’écarts entre les nombres premiers potentiels pour réduire considérablement le nombre de divisions d’essai. Ici nous utilisons une roue 2,3,5:

def factors(n):
    gaps = [1,2,2,4,2,4,2,4,6,2,6]
    length, cycle = 11, 3
    f, fs, nxt = 2, [], 0
    while f * f <= n:
        while n % f == 0:
            fs.append(f)
            n /= f
        f += gaps[nxt]
        nxt += 1
        if nxt == length:
            nxt = cycle
    if n > 1: fs.append(n)
    return fs

Ainsi, print factors(13290059) générera [3119, 4261]. Les roues de factorisation ont la même complexité temporelle O(sqrt(n)) que la division d’essai normale, mais seront deux ou trois fois plus rapides dans la pratique.

J'ai beaucoup travaillé avec les nombres premiers sur mon blog . S'il vous plaît, n'hésitez pas à visiter et à étudier. 

6
user448810

La plupart des solutions ci-dessus semblent quelque peu incomplètes. Une factorisation en nombre premier répète chaque facteur premier du nombre (e.g. 9 = [3 3])

De plus, les solutions ci-dessus pourraient être écrites comme des fonctions paresseuses pour faciliter la mise en œuvre. 

L'utilisation desieve Of Eratosthenespour rechercher les nombres premiers à tester est optimale, mais; l'implémentation ci-dessus a utilisé plus de mémoire que nécessaire. 

Je ne sais pas si/comment"wheel factorization"serait supérieur à l'application de facteurs premiers uniquement, pour les tests de division de n.

Bien que ces solutions soient effectivement utiles, je suggérerais les fonctions suivantes: deux fonctions -

Fonction-1:

def primes(n):
    if n < 2: return
    yield 2
    plist = [2]
    for i in range(3,n):
        test = True
        for j in plist:
            if j>n**0.5:
                break
            if i%j==0:
                test = False
                break
        if test:
            plist.append(i)
            yield i

Fonction 2:

def pfactors(n):
    for p in primes(n):
        while n%p==0:
            yield p
            n=n//p
            if n==1: return

list(pfactors(99999))
[3, 3, 41, 271]

3*3*41*271
99999

list(pfactors(13290059))
[3119, 4261]

3119*4261
13290059
3
Mike Lisanke

J'ai modifié la réponse de @ user448810 pour qu'elle utilise des itérateurs d'itertools (et de python3.4, mais cela devrait être back-portable). La solution est environ 15% plus rapide.

import itertools

def factors(n):
    f = 2
    increments = itertools.chain([1,2,2], itertools.cycle([4,2,4,2,4,6,2,6]))
    for incr in increments:
        if f*f > n:
            break
        while n % f == 0:
            yield f
            n //= f
        f += incr
    if n > 1:
        yield n

Notez que cela retourne un itérable, pas une liste. Enveloppez-le dans la liste () si c'est ce que vous voulez.

3
Chris Cogdon
def get_prime_factors(number):
    """
    Return prime factor list for a given number
        number - an integer number
        Example: get_prime_factors(8) --> [2, 2, 2].
    """
    if number == 1:
        return []

    # We have to begin with 2 instead of 1 or 0
    # to avoid the calls infinite or the division by 0
    for i in xrange(2, number):
        # Get remainder and quotient
        rd, qt = divmod(number, i)
        if not qt: # if equal to zero
            return [i] + get_prime_factors(rd)

    return [number]
1
kadi

facteurs premiers d'un nombre:

def primefactors(x):
    factorlist=[]
    loop=2
    while loop<=x:
        if x%loop==0:
            x//=loop
            factorlist.append(loop)
        else:
            loop+=1
    return factorlist

x = int(input())
alist=primefactors(x)
print(alist)

Vous obtiendrez la liste . Si vous voulez obtenir les paires de facteurs premiers d’un nombre, essayez ceci: http://pythonplanet.blogspot.in/2015/09/list-of-all -unique-paires-of-prime.html

0
user5342177
def prime_factors(num, dd=2):
    while dd <= num and num>1:
        if num % dd == 0:
            num //= dd
            yield dd
        dd +=1

Beaucoup de réponses ci-dessus échouent sur les petits nombres premiers, par exemple. 3, 5 et 7. Ce qui précède est succinct et suffisamment rapide pour un usage ordinaire.

imprimer la liste (prime_factors (3))

[3]

0
jorjun

Je voudrais partager mon code pour trouver les facteurs premiers du nombre donné par l'utilisateur:

a = int(input("Enter a number: "))

def prime(a):
    b = list()
    i = 1
    while i<=a:
        if a%i ==0 and i!=1 and i!=a:
            b.append(i)
        i+=1
    return b

c = list()
for x in prime(a):
    if len(prime(x)) == 0:
        c.append(x)

print(c)
0
vedang joshi

La plupart des réponses rendent les choses trop complexes. Nous pouvons le faire

def prime_factors(n):
    num = []

    #add 2 to list or prime factors and remove all even numbers(like sieve of ertosthenes)
    while(n%2 == 0):
        num.append(2)
        n /= 2

    #divide by odd numbers and remove all of their multiples increment by 2 if no perfectlly devides add it
    for i in xrange(3, int(sqrt(n))+1, 2):
        while (n%i == 0):
            num.append(i)
            n /= i

    #if no is > 2 i.e no is a prime number that is only divisible by itself add it
    if n>2:
        num.append(n)

    print (num)

Algorithme de GeeksforGeeks

0
Amit Tripathi