我有一个函数可以查找数字的素因数并返回其素因子列表:
def prime_factors(n, listFact=[]):
end = floor(sqrt(n))
if n == 1:
return listFact
elif n % 2 == 0:
return prime_factors(n // 2, listFact + [2])
elif n % 3 == 0:
return prime_factors(n // 3, listFact + [3])
for j in range(6, end + 2, 6):
p1, p2 = j - 1, j + 1
if n % p1 == 0:
return prime_factors(n // p1, listFact + [p1])
elif n % p2 == 0:
return prime_factors(n // p2, listFact + [p2])
return listFact + [n]
所以,prime_factors(120) = [2, 2, 2, 3, 5]。
如何从该列表中最佳地计算除数?我的方法非常麻烦,通过添加一个名为 counts 的函数来返回每个因素出现时间的字典。因此,counts(prime_factors(120)) = {2: 3, 3: 1, 5: 1}。程序是:
def find_divisors_v2(n):
dict_primes = counts(prime_factors(n))
big_list = []
for k, v in dict_primes.items():
big_list.append([(k, i) for i in range(v+1)])
divisors_perms = list(itertools.product(*big_list))
divisors = []
for perm in divisors_perms:
d = 1
for i in perm:
d *= i[0]**i[1]
divisors.append(d)
return divisors
但令人惊讶的是,它比通常的方式计算要快,即:
def find_divisors(n):
divisors = []
bound = ceil(sqrt(n)) + 1
for d in range(1, bound):
if n // d == d:
divisors.append(d)
elif n % d == 0:
divisors.append(d)
divisors.append(n//d)
return divisors
有没有一种方法可以从素因数列表中提取除数,并且计算效率更高?或者可以通过修改 prime_factors 函数来实现?