Prime factorization - list

前端 未结 17 783
说谎
说谎 2020-11-27 05:06

I am trying to implement a function primeFac() that takes as input a positive integer n and returns a list containing all the numbers in the prime

相关标签:
17条回答
  • 2020-11-27 05:21

    Here is an efficient way to accomplish what you need:

    def prime_factors(n): 
      l = []
      if n < 2: return l
      if n&1==0:
        l.append(2)
        while n&1==0: n>>=1
      i = 3
      m = int(math.sqrt(n))+1
      while i < m:
        if n%i==0:
          l.append(i)
          while n%i==0: n//=i
        i+= 2
        m = int(math.sqrt(n))+1
      if n>2: l.append(n)
      return l
    

    prime_factors(198765430488765430290) = [2, 3, 5, 7, 11, 13, 19, 23, 3607, 3803, 52579]

    0 讨论(0)
  • 2020-11-27 05:23

    The primefac module does factorizations with all the fancy techniques mathematicians have developed over the centuries:

    #!python
    
    import primefac
    import sys
    
    n = int( sys.argv[1] )
    factors = list( primefac.primefac(n) )
    print '\n'.join(map(str, factors))
    
    0 讨论(0)
  • 2020-11-27 05:25

    A simple trial division:

    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
    

    with O(sqrt(n)) complexity (worst case). You can easily improve it by special-casing 2 and looping only over odd d (or special-casing more small primes and looping over fewer possible divisors).

    0 讨论(0)
  • 2020-11-27 05:25

    Most of the above solutions appear somewhat incomplete. A prime factorization would repeat each prime factor of the number (e.g. 9 = [3 3]).

    Also, the above solutions could be written as lazy functions for implementation convenience.

    The use sieve Of Eratosthenes to find primes to test is optimal, but; the above implementation used more memory than necessary.

    I'm not certain if/how "wheel factorization" would be superior to applying only prime factors, for division tests of n.

    While these solution are indeed helpful, I'd suggest the following two functions -

    Function-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
    

    Function-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
    
    0 讨论(0)
  • 2020-11-27 05:25

    Most of the answer are making things too complex. We can do this

    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)
    

    Algorithm from GeeksforGeeks

    0 讨论(0)
  • 2020-11-27 05:30

    This is a comprehension based solution, it might be the closest you can get to a recursive solution in Python while being possible to use for large numbers.

    You can get proper divisors with one line:

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

    then we can test for a number in divisors to be prime:

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

    which tests that no other divisors divides d.

    Then we can filter prime divisors:

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

    Of course, it can be combined in a single function:

    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 ) ]
    

    Here, the \ is there to break the line without messing with Python indentation.

    0 讨论(0)
提交回复
热议问题