3 回答

TA貢獻1866條經驗 獲得超5個贊
給定您的factorGenerator函數,這是一個應該工作的divisorGen:
def divisorGen(n):
factors = list(factorGenerator(n))
nfactors = len(factors)
f = [0] * nfactors
while True:
yield reduce(lambda x, y: x*y, [factors[x][0]**f[x] for x in range(nfactors)], 1)
i = 0
while True:
f[i] += 1
if f[i] <= factors[i][1]:
break
f[i] = 0
i += 1
if i >= nfactors:
return
該算法的整體效率將完全取決于factorGenerator的效率。

TA貢獻1757條經驗 獲得超8個贊
您應該只在1到n的平方根之間運行循環。然后找到對,執行n / i,這將覆蓋整個問題空間。
還應指出的是,這是一個NP或“困難”的問題。窮舉搜索(您正在執行的方式)與保證答案的效果差不多。加密算法等使用此事實來幫助保護它們。如果有人要解決這個問題,那么我們目前大多數的“安全”通信,即使不是全部,也會變得不安全。
Python代碼:
import math
def divisorGenerator(n):
? ? large_divisors = []
? ? for i in xrange(1, int(math.sqrt(n) + 1)):
? ? ? ? if n % i == 0:
? ? ? ? ? ? yield i
? ? ? ? ? ? if i*i != n:
? ? ? ? ? ? ? ? large_divisors.append(n / i)
? ? for divisor in reversed(large_divisors):
? ? ? ? yield divisor
print list(divisorGenerator(100))
應該輸出如下列表:
[1、2、4、5、10、20、25、50、100]

TA貢獻1827條經驗 獲得超8個贊
盡管已經有很多解決方案,但我確實必須發布此內容:)
快速(在有很多主要因素和因數的情況下,比公認的解決方案快10倍以上)
符合python3,python2和pypy
碼:
def divisors(n):
? ? # get factors and their counts
? ? factors = {}
? ? nn = n
? ? i = 2
? ? while i*i <= nn:
? ? ? ? while nn % i == 0:
? ? ? ? ? ? factors[i] = factors.get(i, 0) + 1
? ? ? ? ? ? nn //= i
? ? ? ? i += 1
? ? if nn > 1:
? ? ? ? factors[nn] = factors.get(nn, 0) + 1
? ? primes = list(factors.keys())
? ? # generates factors from primes[k:] subset
? ? def generate(k):
? ? ? ? if k == len(primes):
? ? ? ? ? ? yield 1
? ? ? ? else:
? ? ? ? ? ? rest = generate(k+1)
? ? ? ? ? ? prime = primes[k]
? ? ? ? ? ? for factor in rest:
? ? ? ? ? ? ? ? prime_to_i = 1
? ? ? ? ? ? ? ? # prime_to_i iterates prime**i values, i being all possible exponents
? ? ? ? ? ? ? ? for _ in range(factors[prime] + 1):
? ? ? ? ? ? ? ? ? ? yield factor * prime_to_i
? ? ? ? ? ? ? ? ? ? prime_to_i *= prime
? ? # in python3, `yield from generate(0)` would also work
? ? for factor in generate(0):
? ? ? ? yield factor
添加回答
舉報