我有一段不太了解的代码,因为我一周前才开始学习Python。
import numpy as np
import time
start_time=time.clock()
def Sieb(n): #Sieve
Eins = np.ones(n, dtype=bool) #Eins is just german for One
Eins[0] = Eins[1] = False #->I don't quite understand what
for i in range(2, n): #this one does.
if Eins[i]:
Eins[i*i::i] = False #Does this make the ones = zero?
return np.flatnonzero(Eins)
print Sieb(1000000)
print start_time
所以,我了解筛子的概念(我想),但是我不确定在这里如何实现。
自身的倍数在哪里0
,np.flatnonzero
如何得出质数,因为在此之前它们分别是1
和0
?
希望您能理解并帮助我。 :)
答案 0 :(得分:2)
Eins = np.ones(n, dtype=bool)
这将创建一个大小为 n 的新数组,类型为bool
,并且全为1。由于类型的原因,“一个”表示True
。该数组表示我们要测试其素数的所有数字,其中True
表示该数字是质数,False
表示不是。因此,我们从标记为(潜在)素数的所有数字开始。
Eins[0] = Eins[1] = False
现在我们将第0
和第1
个元素设置为False
:0和1都不是素数。
for i in range(2, n):
接下来,我们将迭代所有剩余的数字(从2开始)。我们只需要上到 n 的平方根就可以逃脱,但是为了简单起见,我们遍历了所有数字。
if Eins[i]:
如果数组的第i
个值为True
,则意味着i
是质数。第一次输入此条件是使用i=2
。接下来,我们要从主要候选人中删除所有数字的倍数:
Eins[i*i::i] = False
从Eins[2*i::i] = False
开始,我们可以将这行读为i*i
,这只是一个优化¹。如果2是质数,则表示2 * 2、3 * 2、4 * 2 ...不是,因此我们将倍数设置为False
。索引符号表示“从i*i
到结尾”(由冒号之间的空白表示)“,以i
的步长”。该语句产生数字i*i
,i*(i+1)
,i*(i+2)
,...,因此i
的所有倍数尚未标记为“不是质数”。
return np.flatnonzero(Eins)
这只是返回所有值为True
的索引,即找到的所有素数。
1:关于i*i
的一句话:我们可以从i
的平方开始,因为任何数字j*i
(对于j < i
)已经被标记为非质数当我们在j
时。
n=15
有效的演示:我们从填充.ones
的数组开始:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
[T, T, T, T, T, T, T, T, T, T, T, T, T, T, T]
然后我们清空Eins[0]
和Eins[1]
:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
[F, F, T, T, T, T, T, T, T, T, T, T, T, T, T]
现在我们从i=2
开始遍历整个范围,并从2*2=4
开始删除2的每一个倍数:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
[F, F, T, T, F, T, F, T, F, T, F, T, F, T, F]
i=3
,从3*3=9
开始删除3的倍数:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
[F, F, T, T, F, T, F, T, F, F, F, T, F, T, F]
请注意,我们不必删除6
,因为i=2
已经删除了它。
在i=4
时,由于Eins[i]
为False
,因此我们跳过了删除操作。从i=5
开始,什么都没有发生,因为正方形(25,36,...)比数组大。最后,我们使用flatnonzero
并获取所有值为True
的索引:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
[F, F, T, T, F, T, F, T, F, F, F, T, F, T, F]
2 3 5 7 11 13