【问题标题】:Understanding Prime Sieve了解初筛
【发布时间】:2020-03-09 06:04:23
【问题描述】:

我试图了解用户对 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 循环!在那之后,如果声明,我完全迷失了。如果有人可以提供帮助,那就太好了!

【问题讨论】:

  • 它首先假设直到n 的所有数字都是素数,然后将不是素数的数字标记为False。这就是筛子的工作原理。 for 循环通过从 3 开始步进 2 跳过偶数: [3, 5, 7, 9, ...] 第三个参数是步长。

标签: python primes sieve


【解决方案1】:

也许我下面的代码注释可能对您有所帮助——我还尽可能简化了代码(希望没有破坏它!):

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 中的元素数量减少一半,而不是存储它忽略的偶数元素。当然,这会使索引变得更加复杂,但却是可行的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-20
    相关资源
    最近更新 更多