我正在尝试实现维基百科链接中给出的Atve筛选算法,如下所示:
到目前为止,我尝试过的是使用以下代码给出的Python实现:
import math
is_prime = list()
limit = 100
for i in range(5,limit):
is_prime.append(False)
for x in range(1,int(math.sqrt(limit))+1):
for y in range(1,int(math.sqrt(limit))+1):
n = 4*x**2 + y**2
if n<=limit and (n%12==1 or n%12==5):
# print "1st if"
is_prime[n] = not is_prime[n]
n = 3*x**2+y**2
if n<= limit and n%12==7:
# print "Second if"
is_prime[n] = not is_prime[n]
n = 3*x**2 - y**2
if x>y and n<=limit and n%12==11:
# print "third if"
is_prime[n] = not is_prime[n]
for n in range(5,int(math.sqrt(limit))):
if is_prime[n]:
for k in range(n**2,limit+1,n**2):
is_prime[k] = False
print 2,3
for n in range(5,limit):
if is_prime[n]: print n
现在我收到错误
is_prime[n] = not is_prime[n]
IndexError: list index out of range
这意味着我正在访问列表中的值,其中索引大于List的长度。考虑x,y = 100时的条件,然后当然条件n = 4x ^ 2 + y ^ 2将给出大于列表长度的值。我在这里做错了吗?请帮忙。
编辑1 正如Gabe所建议的,使用
is_prime = [False] * (limit + 1)
绝对:
for i in range(5,limit):
is_prime.append(False)
确实解决了这个问题。
答案 0 :(得分:4)
这是一个解决方案
import math
def sieveOfAtkin(limit):
P = [2,3]
sieve=[False]*(limit+1)
for x in range(1,int(math.sqrt(limit))+1):
for y in range(1,int(math.sqrt(limit))+1):
n = 4*x**2 + y**2
if n<=limit and (n%12==1 or n%12==5) : sieve[n] = not sieve[n]
n = 3*x**2+y**2
if n<= limit and n%12==7 : sieve[n] = not sieve[n]
n = 3*x**2 - y**2
if x>y and n<=limit and n%12==11 : sieve[n] = not sieve[n]
for x in range(5,int(math.sqrt(limit))):
if sieve[x]:
for y in range(x**2,limit+1,x**2):
sieve[y] = False
for p in range(5,limit):
if sieve[p] : P.append(p)
return P
print sieveOfAtkin(100)
答案 1 :(得分:3)
您的问题是,您的限制为100,但由于is_prime
初始化,您的limit-5
列表中只有range(5, limit)
个元素。
由于此代码假定它最多可以访问limit
索引,因此您需要包含limit+1
个元素:is_prime = [False] * (limit + 1)
请注意,4x^2+y^2
大于limit
并不重要,因为它始终会检查n <= limit
。