我正在构建一个程序,使用python使用Eratosthenes筛子的算法来查找所有小于n的素数。 该算法首先创建一个2到n的数字列表,然后在该列表上进行迭代,以删除可用的第一个元素和相应的倍数。问题是我这样做似乎没有得到正确的结果。我也很感谢任何改进性能的建议。
这是算法:
Then
(已解决)这是我的更改方式:
def primes(max):
'''The sieve of Eratosthenes
Algorithm to find all primes smaller than max'''
init = time.clock()
allNum = [a for a in range(2, max+1)]
primes = []
for n in allNum:
# remove all multiples of prime n
toRemove = (a for a in range(n, max+1, n) if a in allNum)
for i in toRemove:
print('toRemove:', i)
allNum.remove(i)
# add the prime to the list
primes.append(n)
deltaT = time.clock() - init
print('Time taken to process:', deltaT)
return primes
答案 0 :(得分:1)
一种更快的选择是建立一个布尔值列表(全部为True),并使用算法将它们设置为False。质数是列表中所有保留为true的索引:
def primes(max):
mask = [True for i in range(0,max + 1)]
for num in range(2,max):
if not mask[num]:
continue
for multiple in range(num*2, max+1, num):
mask[multiple] = False
primes = [i for i,mask_value in enumerate(mask) if mask_value]
return primes[2:]
答案 1 :(得分:0)
遍历列表时,将引用每个偏移量,而不是每个值。例如,当您获得第一个结果时,如果它符合条件并删除该值,则所有后续值都将向前滑动,并且偏移量将递增。您的偏移量现在是索引1(以0为底)。但是您只是删除了索引0,一切都向前滑了。您基本上跳过了第二个数字。
0$ python3
Python 3.4.8 (default, Mar 23 2018, 10:04:27)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> [a for a in range(1, 20)]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> the_list = [a for a in range(1, 20)]
>>> for a in the_list:
... the_list.remove(a)
...
>>> the_list
[2, 4, 6, 8, 10, 12, 14, 16, 18]
>>>
答案 2 :(得分:-1)
我不认为您可以在迭代列表时更改列表。
您可以切换到while循环,只要原始列表中保留任何数字,该循环就会运行。对于每次迭代,至少要删除第一个数字:如果为质数,则将其移至质数列表;如果不是质数,则将其及其所有倍数删除。