做不是迭代通过一组数字测试每个素数。这将是不可能的缓慢。您正在寻找的算法被称为Eratosthenes的分割筛。
虽然Eratosthenes的筛网速度非常快,但它需要O(n)空间。对于筛选素数,可以通过在连续的片段中执行筛分将其减少到O(sqrt(n))加上O(1)的比特数。在第一个分段中,计算分段内每个筛分质数的最小倍数,然后以正常方式标记复合质量的多个筛分质数;当使用所有筛分质数时,该分段中剩余的未标记数字是质数。然后,对于下一个分段,每个筛分质数的最小倍数是在前一个分段中结束筛分的倍数,因此筛分继续直到完成。
考虑从20到200的分段筛选100到200的例子; 5个筛选素数是3,5,7,11和13.在100到120的第一段中,比特数有10个时隙,其中时隙0对应于101,时隙k对应于100 + 2k-1,时隙9对应于119.分段中的3的最小倍数是105,对应于时隙2;时隙2 + 3 = 5和5 + 3 = 8也是3的倍数。时隙2处的5的最小倍数是105,时隙2 + 5 = 7也是5的倍数.7的最小倍数是105在时隙2处,时隙2 + 7 = 9也是7的倍数。依此类推。
函数素数需要参数lo,hi和delta; lo和hi必须是偶数,并且lo必须大于天花板(sqrt(hi))。段的大小是两倍三角洲。长度为m的数组ps包含小于sqrt(hi)的筛选素数,删除2,因为偶数会被忽略,并且数组qs包含到相应筛选素数当前片段中最小倍数的筛子位阵列的偏移量。每个段之后,LO通过两次增量前进,所以对应于筛bitarray的索引j的数目为LO + 2J + 1
function primes(lo, hi, delta)
sieve := makeArray(0..delta-1) # bitarray
# calculate m and ps as described in text
qs := makeArray(0..m-1) # least multiples
for i from 0 to m-1
qs[i] := (-1/2 * (lo + ps[i] + 1)) % ps[i]
while lo < hi
for i from 0 to delta-1
sieve[i] := True
for i from 0 to m-1
for j from qs[i] to delta step ps[i]
sieve[j] := False
qs[i] := (qs[i] - delta) % ps[i]
for i from 0 to delta-1
t := lo + 2*j + 1
if sieve[i] and t < hi
output t
lo := lo + 2*delta
对于上面给出的样品,这被称为质数(100, 200,10)。在上面给出的例子中,qs最初是[2,2,2,10,8],对应于最小倍数105,105,105,121和117,并且针对第二段重置为[1,2,6, 0,11],对应于最小倍数123,125,133,121和143。该算法非常快;你应该能够在不到一秒的时间内生成几百万个素数。
如果您想了解更多关于使用素数编程的信息,我会在我的博客上谦虚地推荐this essay。
这是写什么语言? – Jon
它有多准确?你能接受卡迈克尔号码吗?以及'isprime'如何实现? – tjameson
我正在使用matlab 2012,准确性很重要,但不是这里最重要的。你的意思是卡迈克尔的数字。 isprime检查每个值,看它是否实际上是素数。 – user1825494