了解素筛
Understanding Prime Sieve
我正在尝试了解用户对 Erastothene 的 Prime Seive 的实施情况;代码只有几行,但我很难理解它:
def eratos_sieve(n):
sieve = [True] * n
for i in range(3,int(n**0.5)+1,2):
if sieve[i]:
sieve[i*i::2*i]=[False]*((n-i*i-1)//(2*i)+1)
return len([2] + [i for i in range(3,n,2) if sieve[i]])
到目前为止我的不理解是:我们正在定义一个带有参数 n 的函数。我们首先假设 n 是素数。然后,出于某种原因,我们有一个带有 3 个参数的 for 循环!在那个 if 语句之后,我完全迷路了。如果有人能提供帮助,那就太好了!
也许我下面的代码评论可能对您有所帮助——我还尽可能地简化了代码(希望没有破坏它!):
def eratos_sieve(n):
''' Return the number of primes less than n '''
# Create an array [True, True, True, ...] of length n
# i.e. assume all numbers are prime unless proven otherwise
sieve = [True] * n
# loop over odd numbers from 3 to sqrt(n)
for i in range(3, int(n**0.5) + 1, 2):
if sieve[i]: # if sieve[i] is still True, i is a prime!
# Assign elements of sieve from i squared to the
# end of the array skipping by 2 * i (hit multiples
# of i but skip the even ones) to False. Since this
# is an array to array assignment, create an array of
# [False, False, False, ...] of the correct size:
sieve[i*i::2*i] = [False] * ((n-i * i-1) // (i*2) + 1)
# Add up odd elements of sieve (True = 1, False = 0),
# Add one for '2' which we assumed prime:
return 1 + sum(sieve[3::2])
代码有点复杂,因为它跳过了偶数,这很好。更优化的解决方案还将 sieve
中的元素数量减少一半,而不是存储它忽略的偶数元素。当然,这会使索引更复杂,但可行。
我正在尝试了解用户对 Erastothene 的 Prime Seive 的实施情况;代码只有几行,但我很难理解它:
def eratos_sieve(n):
sieve = [True] * n
for i in range(3,int(n**0.5)+1,2):
if sieve[i]:
sieve[i*i::2*i]=[False]*((n-i*i-1)//(2*i)+1)
return len([2] + [i for i in range(3,n,2) if sieve[i]])
到目前为止我的不理解是:我们正在定义一个带有参数 n 的函数。我们首先假设 n 是素数。然后,出于某种原因,我们有一个带有 3 个参数的 for 循环!在那个 if 语句之后,我完全迷路了。如果有人能提供帮助,那就太好了!
也许我下面的代码评论可能对您有所帮助——我还尽可能地简化了代码(希望没有破坏它!):
def eratos_sieve(n):
''' Return the number of primes less than n '''
# Create an array [True, True, True, ...] of length n
# i.e. assume all numbers are prime unless proven otherwise
sieve = [True] * n
# loop over odd numbers from 3 to sqrt(n)
for i in range(3, int(n**0.5) + 1, 2):
if sieve[i]: # if sieve[i] is still True, i is a prime!
# Assign elements of sieve from i squared to the
# end of the array skipping by 2 * i (hit multiples
# of i but skip the even ones) to False. Since this
# is an array to array assignment, create an array of
# [False, False, False, ...] of the correct size:
sieve[i*i::2*i] = [False] * ((n-i * i-1) // (i*2) + 1)
# Add up odd elements of sieve (True = 1, False = 0),
# Add one for '2' which we assumed prime:
return 1 + sum(sieve[3::2])
代码有点复杂,因为它跳过了偶数,这很好。更优化的解决方案还将 sieve
中的元素数量减少一半,而不是存储它忽略的偶数元素。当然,这会使索引更复杂,但可行。