python - 为什么我的埃拉托色尼筛法运行得这么慢?

标签 python algorithm primes sieve-of-eratosthenes

我正在用 Python 为埃拉托色尼筛法编写素数程序。虽然它看起来有效,但速度很慢。我怎样才能加快速度?

primes = []
upperLimit = 1000

for x in range(2,upperLimit):
  primes.append(x)
for y in range(0,int(len(primes)**0.5)):
  remove = []
  for j in range(primes[y]**2,upperLimit,primes[y]):
    remove.append(j)
  for i in remove:
    if i in primes:
      primes.remove(i)

print(primes)

更新: 多亏了答案的帮助,我使用 bool 值而不是数字重写了代码。低于 100000 的列表现在运行不到 6 秒。

i = 2
limit = 100000
primes = [True] * limit
primes[0] = False
while i < limit**0.5:
    if primes[i-1]:
        for x in range(i * 2, limit + 1,i):
            primes[x-1] = False
    i += 1
count = 1
total = []
for i in primes:
    if i:
        total.append(count)
    count += 1
print(total)

最佳答案

我认为您代码中的主要低效率是您维护的质数列表。尽管可能并不明显,但调用 primes.remove 是一项非常昂贵的操作。它需要遍历 list 以尝试找到您要删除的值,然后它需要修改 list 通过将所有元素移动到您的元素之后正在寻找。

例如

l = [0, 1, 2, 3, 4]
l.remove(5)  # This has to look at all the elements in l, since 6 isn't there
l.remove(0)  # This finds 1 quickly but then has to move every element to the left

Eratosthenes 筛法的一种更传统的方法是使用您正在考虑的所有数字的数组(Python 中的 list),其中每个元素都是一个 bool 值,指示该数字是否可以是素数。

模仿上面的例子:

l = [True, True, True, True, True]
l[0] = False  # Just goes straight to that element and changes its value

下面是如何编写该代码的示例:

primes = [True] * 100000

# We already know 2 is the first prime
primes[0] = False
primes[1] = False

# Fine to stop at sqrt(len(primes)) here as you're already doing    
for i in range(2, len(primes)):
    if primes[i]:
        for j in range(i**2, len(primes), i):
            primes[j] = False

print([n for n, is_prime in enumerate(primes) if is_prime])

您会发现这要快得多,因为索引到 list 并以这种方式更改值非常有效。

关于python - 为什么我的埃拉托色尼筛法运行得这么慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46656172/

相关文章:

python - ast.literal_eval 用于 python 中的变量?

algorithm - 哈希排序与快速排序的比较

python - numpy fft 对于小素数乘积的长度很快,但是有多小?

python - numpy.vectorize : Why so slow?

python - 我的过滤器无法工作,尽管它们应该工作相同

python - 如何根据用户操作有选择地切换 OpenCV 的 VideoWriter

algorithm - Matlab 中的离散傅里叶变换 - 理论困惑

algorithm - Fischer 互斥算法

java - java中的素数生成器

conditional-statements - Lisp - 无论如何执行 "when"条件?