26

我正在尝试实现一个函数,该函数primeFac()将一个正整数作为输入n,并返回一个包含 的素数分解中的所有数字的列表n

我已经做到了这一点,但我认为在这里使用递归会更好,不知道如何在这里创建递归代码,基本情况是什么?开始。

我的代码:

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

17 回答 17

50

一个简单的试除法:

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

具有O(sqrt(n))复杂性(最坏情况)。您可以通过特殊情况 2 并仅在奇数上循环d(或特殊情况下更小的素数并在更少可能的除数上循环)来轻松改进它。

于 2013-06-08T05:32:03.690 回答
15

这是一个基于理解的解决方案,它可能最接近 Python 中的递归解决方案,同时可以用于大量数字。

你可以用一行得到适当的除数:

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

然后我们可以测试除数中的一个数是否为素数:

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

它测试没有其他除数除以 d。

然后我们可以过滤素数除数:

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

当然,它可以组合成一个函数:

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

在这里,\ 可以在不影响 Python 缩进的情况下换行。

于 2013-06-08T05:46:58.540 回答
12

primefac模块使用数学家几个世纪以来开发的所有花哨技术进行因式分解:

#!python

import primefac
import sys

n = int( sys.argv[1] )
factors = list( primefac.primefac(n) )
print '\n'.join(map(str, factors))
于 2016-01-28T23:49:26.820 回答
6

这是我的试验除法分解版本,它结合了仅除以二的优化和 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

对二和奇数的试除法的改进是轮因式分解,它使用潜在素数之间的一组循环间隙来大大减少试除法的数量。这里我们使用 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

因此,print factors(13290059)将输出[3119, 4261]. 因式分解轮具有与正常试验除法相同的 O(sqrt(n)) 时间复杂度,但在实践中会快两到三倍。

我在我的博客上做了很多关于素数的工作。请随时参观和学习。

于 2013-06-08T14:23:48.467 回答
6

我已经调整了@user448810 的答案以使用来自 itertools 的迭代器(和 python3.4,但它应该是可向后移植的)。该解决方案的速度提高了约 15%。

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

请注意,这将返回一个可迭代的,而不是一个列表。如果这是您想要的,请将其包装在 list() 中。

于 2015-08-29T02:02:32.557 回答
5

大多数上述解决方案似乎有些不完整。质因数分解将重复数字的每个质因数(e.g. 9 = [3 3])

此外,为了实现方便,上述解决方案可以写成惰性函数。

使用sieve Of Eratosthenes寻找素数进行测试是最佳的,但是;上面的实现使用了比需要更多的内存。

对于 n 的除法测试,我不确定是否/如何"wheel factorization"优于仅应用素因子。

虽然这些解决方案确实很有帮助,但我建议使用以下两个功能 -

功能一:

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

功能 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
于 2015-01-31T10:14:14.747 回答
3
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]
于 2015-06-17T13:19:12.723 回答
1

这是完成您需要的有效方法:

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]

于 2020-04-09T15:08:55.453 回答
1

数的质因数:

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)

你会得到清单。如果你想得到一个数的素数对,试试这个: http: //pythonplanet.blogspot.in/2015/09/list-of-all-unique-pairs-of-prime.html

于 2015-09-16T12:12:57.430 回答
1

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

于 2015-09-13T17:42:42.390 回答
0

您可以使用sieve Of Eratosthenes生成所有素数(n/2) + 1,然后使用列表推导来获取所有素数:

def rwh_primes2(n):
    # http://stackoverflow.com/questions/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188
    """ Input n>=6, Returns a list of primes, 2 <= p < n """
    correction = (n%6>1)
    n = {0:n,1:n-1,2:n+4,3:n+3,4:n+2,5:n+1}[n%6]
    sieve = [True] * (n/3)
    sieve[0] = False
    for i in xrange(int(n**0.5)/3+1):
      if sieve[i]:
        k=3*i+1|1
        sieve[      ((k*k)/3)      ::2*k]=[False]*((n/6-(k*k)/6-1)/k+1)
        sieve[(k*k+4*k-2*k*(i&1))/3::2*k]=[False]*((n/6-(k*k+4*k-2*k*(i&1))/6-1)/k+1)
    return [2,3] + [3*i+1|1 for i in xrange(1,n/3-correction) if sieve[i]]

def primeFacs(n):
    primes = rwh_primes2((n/2)+1)
    return [x for x in primes if n%x == 0]

print primeFacs(99999)
#[3, 41, 271]
于 2013-06-08T05:19:55.763 回答
0
def factorize(n):
  for f in range(2,n//2+1):
    while n%f == 0:
      n //= f
      yield f

它很慢但很简单。如果要创建命令行实用程序,可以执行以下操作:

import sys
[print(i) for i in factorize(int(sys.argv[1]))]
于 2014-03-28T11:48:50.740 回答
0
def prime_factors(num, dd=2):
    while dd <= num and num>1:
        if num % dd == 0:
            num //= dd
            yield dd
        dd +=1

上面的很多答案在小素数上都失败了,例如 3、5 和 7。上面的内容简洁而快速,足以满足普通使用。

打印列表(prime_factors(3))

[3]

于 2018-07-01T11:09:45.560 回答
0

我想分享我的代码来查找用户输入的数字的主要因素:

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)
于 2018-06-27T18:13:53.980 回答
-1

这是我制作的代码。它适用于具有小素数的数字,但对于具有数百万素数的数字则需要一段时间。

def pfactor(num):
div = 2
pflist = []
while div <= num:
    if num % div == 0:
        pflist.append(div)
        num /= div
    else:
        div += 1
# The stuff afterwards is just to convert the list of primes into an expression
pfex = ''
for item in list(set(pflist)):
    pfex += str(item) + '^' + str(pflist.count(item)) + ' * '
pfex = pfex[0:-3]
return pfex
于 2018-01-30T02:16:39.753 回答
-1

获得所需解决方案的简单方法

def Factor(n):
    d = 2
    factors = []
    while n >= d*d:
        if n % d == 0:
            n//=d
            # print(d,end = " ")
            factors.append(d)
        else:
            d = d+1
    if n>1:
        # print(int(n))
        factors.append(n)
    return factors
于 2016-09-19T08:15:22.570 回答
-1
    from sets import Set
    # this function generates all the possible factors of a required number x
    def factors_mult(X):
        L = []
        [L.append(i) for i in range(2,X) if X % i == 0]
        return L

    # this function generates list containing prime numbers upto the required number x 
    def prime_range(X):
        l = [2]
        for i in range(3,X+1):
            for j in range(2,i):
               if i % j == 0:
               break
            else:    
               l.append(i)
        return l

    # This function computes the intersection of the two lists by invoking Set from the sets module
    def prime_factors(X):
        y = Set(prime_range(X))
        z = Set(factors_mult(X))
        k = list(y & z)
        k = sorted(k)

        print "The prime factors of " + str(X) + " is ", k

    # for eg
    prime_factors(356)
于 2015-07-28T10:29:34.310 回答