在互联网上浮动的许多原始测试中,考虑以下主要测试:
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()截断该值)
由于前几个测试,而在循环中间的测试,循环只需要被评估每第六个数字。
考虑下一个奇数(因为除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的速度还要快两倍,因为只有每第6个整数循环遍历循环。 (再一次,我对此进行了基准测试。)
旁注:x ** 0.5是平方根:
>>> import math
>>> math.sqrt(100)==100**0.5
True
附注2:primality testing是计算机科学中的一个有趣的问题。