在网上流传的许多素性测试中,请考虑以下素性测试:def is_prime(n):
if n == 2 or n == 3: return True
if n < 2 or n%2 == 0: return False
if n < 9: return True
if n%3 == 0: return False
r = int(n**0.5)
f = 5
while f <= r:
print '\t',f
if n%f == 0: return False
if n%(f+2) == 0: return False
f +=6
return True
考虑质数5003:print is_prime(5003)
印刷品:5
11
17
23
29
35
41
47
53
59
65
True
行r = int(n**0.5)的值为70(5003的平方根为70.7318881411,int()截断此值)
由于前几个测试,以及循环中间的测试,循环只需要每隔6个数字进行一次评估。
考虑下一个奇数(因为除了2以外的所有偶数都不是素数)5005,同样的东西会打印出来:5
False
极限是平方根,因为x*y == y*x函数只需循环1次,就可以找到5005可被5整除,因此不是素数。因为5 X 1001 == 1001 X 5(两者都是5005),我们不需要一直到循环中的1001就可以知道我们在5点知道了什么!
现在,让我们看看你的算法:def isPrime(n):
for i in range(2,int(n**0.5)+1):
if n%i==0:
return False
return True
有两个问题:它不测试n是否小于2,并且没有小于2的素数
它测试2到n**0.5之间的每个数字,包括所有偶数和所有奇数。因为每一个大于2且可被2整除的数都不是素数,所以我们可以通过只测试大于2的奇数来稍微加快速度。
所以:def isPrime2(n):
if n==2 or n==3: return True
if n%2==0 or n<2: return False
for i in range(3,int(n**0.5)+1,2): # only odd numbers
if n%i==0:
return False
return True
好吧——这就加快了大约30%(我做了基准测试…)
我使用的算法is_prime的速度大约是原来的2倍,因为只有每6个整数在循环中循环。(再一次,我做了基准测试。)
旁注:x**0.5为平方根:>>> import math
>>> math.sqrt(100)==100**0.5
True
旁注2:primality testing是计算机科学中一个有趣的问题。