我正在尝试实现一个函数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... ?
答案 0 :(得分:42)
一个简单的试验部门:
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
(或特殊套管更小的素数并在更少的可能除数上循环)循环。
答案 1 :(得分:13)
这是一个基于理解的解决方案,它可能是最接近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缩进。
答案 2 :(得分:10)
primefac module对数学家几个世纪以来所开发的所有奇特技术进行了分析:
#!python
import primefac
import sys
n = int( sys.argv[1] )
factors = list( primefac.primefac(n) )
print '\n'.join(map(str, factors))
答案 3 :(得分:6)
这是我的试验分解的分解版本,其中包括仅由2分割的优化和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和奇数的改进是轮分解,它使用潜在素数之间的一组循环间隙来大大减少试验分割的数量。这里我们使用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))时间复杂度,但在实践中将快两到三倍。
我在my blog的素数做了很多工作。请随时访问和学习。
答案 4 :(得分:3)
上述大部分解决方案似乎都不完整。素数分解将重复数字(e.g. 9 = [3 3])
的每个素数因子。
此外,上述解决方案可以编写为惰性函数以方便实现。
使用 sieve Of Eratosthenes
来查找要测试的素数是最佳的,但是;上面的实现使用了比必要更多的内存。
我不确定 "wheel factorization"
是否/如何优于仅应用素因子,用于n的除法测试。
虽然这些解决方案确实有用,但我建议以下两个功能 -
功能-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
功能-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
答案 5 :(得分:3)
我已经调整@ 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()中。
答案 6 :(得分:1)
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]
答案 7 :(得分:0)
数字的主要因素:
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
答案 8 :(得分: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)
答案 9 :(得分: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]
答案 10 :(得分:0)
这是完成您所需要的有效方法:
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,11,13,19,23,3607,3803,52579]
答案 11 :(得分:-1)
您可以使用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]
答案 12 :(得分:-1)
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]))]
答案 13 :(得分:-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)
答案 14 :(得分:-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
答案 15 :(得分:-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