对于非常大的数字,我的代码非常慢。
def divisors(num):
divs = 1
if num == 1:
return 1
for i in range(1, int(num/2)):
if num % i == 0:
divs += 1
elif int(num/2) == i:
break
else:
pass
return divs
对于10 ^ 9,我的运行时间为381.63秒。
答案 0 :(得分:3)
这是一种确定n
的各种不同素因子的多重性的方法。每个此类权力k
对除数总数的贡献为k+1
。
import math
def smallest_divisor(p,n):
#returns the smallest divisor of n which is greater than p
for d in range(p+1,1+math.ceil(math.sqrt(n))):
if n % d == 0:
return d
return n
def divisors(n):
divs = 1
p = 1
while p < n:
p = smallest_divisor(p,n)
k = 0
while n % p == 0:
k += 1
n //= p
divs *= (k+1)
return divs - 1
它返回适当除数的数量(因此不计算数字本身)。如果要计算数字本身,请不要从结果中减去1。
它可以使用10 ** 9的数字快速工作,但是如果数字更大则会显着减慢。
答案 1 :(得分:0)
考虑一下:
import math
def num_of_divisors(n):
ct = 1
rest = n
for i in range(2, int(math.ceil(math.sqrt(n)))+1):
while rest%i==0:
ct += 1
rest /= i
print i # the factors
if rest == 1:
break
if rest != 1:
print rest # the last factor
ct += 1
return ct
def main():
number = 2**31 * 3**13
print '{} divisors in {}'.format(num_of_divisors(number), number)
if __name__ == '__main__':
main()
我们可以停止在n
的平方根处搜索因子。在while
循环中找到了多个因子。当找到一个因子时,我们将其从数字中除去
修改强>
@Mark Ransom是对的,对于一个因子大于该数字的平方根的数字,因子计数为1太小,例如3*47*149*6991
。 rest != 1
的最后一次检查说明了这一点。
因素的数量确实是正确的 - 您不必为了sqrt(n)
而检查。{
如果需要,可以使用打印数字的两个语句将此数字附加到因子数。
答案 2 :(得分:0)
分区很贵,乘法便宜。
将数字分解为素数。 (下载素数列表,继续与<= sqrt(num)
分开。)
然后计算所有排列。
如果你的数字恰好是一个素数p^n
的幂,你就可以得到n
除数,不包括1; 8 = 2 ^ 3有3个除数:8,4,2。
一般情况下,您的数字因素为k素数:p0^n0 * p1^n1 * ... * pk^nk
。它有(n0 + 1) * (n1 + 1) * .. * (nk + 1)
个除数。 &#34; + 1&#34;当所有其他幂为0时的情况下的术语计数,即对乘法贡献1。
或者,你可以谷歌和RTFM。
答案 3 :(得分:0)
以下是我在问题中的代码的改进版本。运行时间更好,现在为10 ^ 9,为0.008s。
def divisors(num):
ceiling = int(sqrt(num))
divs = []
if num == 1:
return [1]
for i in range(1, ceiling + 1):
if num % i == 0:
divs.append(num / i)
if i != num // i:
divs.append(i)
return divs
对我来说,保持除数很重要,所以如果这仍然可以 得到改善我很高兴。