我编写并使用此函数来生成数字的素数因子:
import numpy as np
from math import sqrt
def primesfrom3to(n):
""" Returns a array of primes, p < n """
assert n>=2
sieve = np.ones(n/2, dtype=np.bool)
for i in xrange(3,int(n**0.5)+1,2):
if sieve[i/2]:
sieve[i*i/2::i] = False
return np.r_[2, 2*np.nonzero(sieve)[0][1::]+1]
def primefactors(tgt,verbose=True):
if verbose:
print '\n\nFinding prime factors of: {:,}'.format(tgt)
primes=primesfrom3to(sqrt(tgt)+1)
if verbose:
print ('{:,} primes between 2 and square root of tgt ({:.4})'.
format(len(primes),sqrt(tgt)))
return [prime for prime in primes if not tgt%prime]
如果我用Project Euler #3的值调用它,它会成功生成不同素数的列表:
>>> print primefactors(600851475143)
Finding prime factors of: 600,851,475,143
62,113 primes between 2 and square root of tgt (7.751e+05)
[71, 839, 1471, 6857]
这与主要因素的Wolfram Alpha produces一致。 (并且最大的项目欧拉#3正确答案)
现在让我们说我想要那个数字的因子x 1e6:
>>> print primefactors(600851475143*1000000)
Finding prime factors of: 600,851,475,143,000,000
39,932,602 primes between 2 and square root of tgt (7.751e+08)
[2, 5, 71, 839, 1471, 6857]
对于这个较大的数字,Wolfram Alpha produces:
2**6 * 5**6 * 71 * 839 * 1471 * 6857
是否有一种简单的方法来修改我的代码,我可以计算2
和5
的幅度作为较大数字的主要因素?
(我对这个原始代码或算法很感兴趣 - 不是指向我这样做的库的指针,谢谢!)
答案 0 :(得分:8)
这样做的传统方法是依次分出每个素数因子,然后对你的因子分解方法进行说明。这通常比筛选所有素数更快,因为你只关心实际划分数量的(少数)素数。
当然,有许多更好的素数因子分解算法比试验分割更好;人们通常使用类似二次筛的东西用于各种数字,Pollard的rho方法在小端,数字字段在大的筛子上。这些都显着更复杂。
由于您事先正在筛选所有质数,因此您不关心算法的效率。鉴于此,最简单的方法就是找出事后事后的多重性,这就是@tobias_k所写的。您也可以将其分解为单独的函数
def multiplicity(n, p):
i = 0
while not n % p:
i, n = i+1, n/p
return i
然后
>>> n = 600,851,475,143,000,000
>>> n = 600851475143000000
>>> factors = [2, 5, 71, 839, 1471, 6857]
>>> [(f, multiplicity(n,f)) for f in factors]
[(2, 6), (5, 6), (71, 1), (839, 1), (1471, 1), (6857, 1)]
答案 1 :(得分:4)
一旦你有了明显的素因子,你就可以这样做:
factors = []
for f in distinct_prime_factors:
while n % f == 0:
factors.append(f)
n /= f
现在factors
将保留所有主要因素的列表。
答案 2 :(得分:2)
通过这种方式,这更容易(并且速度更快,效率更高):
from collections import defaultdict
from math import sqrt
def factor(n):
i = 2
limit = sqrt(n)
while i <= limit:
if n % i == 0:
yield i
n = n / i
limit = sqrt(n)
else:
i += 1
if n > 1:
yield n
def pfac(num):
d=defaultdict(int)
for f in factor(num):
d[f]+=1
terms=[]
for e in sorted(d.keys()):
if d[e]>1:
terms.append('{:,}^{}'.format(e,d[e]))
else:
terms.append('{:,}'.format(e))
print ' * '.join(terms),'=','{:,}'.format(num)
pfac(600851475143*1000000-1)
pfac(600851475143*1000000)
pfac(600851475143*1000000+1)
打印:
83 * 127 * 57,001,373,222,939 = 600,851,475,142,999,999
2^6 * 5^6 * 71 * 839 * 1,471 * 6,857 = 600,851,475,143,000,000
3^2 * 19 * 103 * 197 * 277 * 16,111 * 38,803 = 600,851,475,143,000,001