在数学和计算机科学中,素数(质数)是一个重要的概念。素数是指大于1的自然数,且只能被1和它本身整除的数。如何高效地找到两个自然数之间的所有素数呢?本文将介绍一种经典的算法——埃拉托斯特尼筛法,并通过 JavaScript 代码实现。
什么是埃拉托斯特尼筛法?
埃拉托斯特尼筛法(简称埃氏筛)是一种用于查找素数的经典算法。它的基本思想是从小到大遍历所有自然数,依次筛去每个素数的倍数,剩下的未被筛去的数就是素数。
算法步骤:
-
列出所有数:从2开始,列出所有需要筛选的自然数。
-
标记倍数:从第一个素数(2)开始,标记其所有倍数为非素数。
-
重复筛选:找到下一个未被标记的数(即素数),并标记其所有倍数。
-
终止条件:当筛选的素数的平方大于最大数时,算法终止,剩下的未被标记的数即为素数。
示例:找出25以内的所有素数
我们以25以内的数为例,详细说明埃氏筛的执行过程:
-
列出所有数
2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,252,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25 -
筛选2的倍数:
记录素数2,从 2^2^ = 4 开始,划去 2 的倍数:4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24。 -
筛选3的倍数:
记录素数3,从 32=932=9 开始,划去3的倍数:9, 12, 15, 18, 21, 24。 -
筛选5的倍数:
记录素数5,从 52=2552=25 开始,划去5的倍数:25。 -
终止筛选:
下一个素数是7,但 72=49>2572=49>25,因此算法终止。 剩下的未被标记的数即为素数:2, 3, 5, 7, 11, 13, 17, 19, 23。
JavaScript 实现
以下是埃氏筛的 JavaScript 实现代码:
function findPrimes(n) {
let signs = new Array(n).fill(false); // 初始化标记数组
let primes = [];
for (let i = 2; i <= n; i++) {
if (!signs[i - 1]) { // 如果当前数未被标记为非素数
primes.push(i); // 记录素数
for (let j = i * i; j <= n; j += i) {
signs[j - 1] = true; // 标记当前素数的倍数
}
}
}
return primes;
}
let n = 25;
console.log(findPrimes(n)); // 输出: [2, 3, 5, 7, 11, 13, 17, 19, 23]
代码解析:
-
初始化标记数组:
signs数组用于标记非素数,初始值为false。 -
遍历筛选:从 2 开始遍历,如果当前数未被标记为非素数,则记录为素数,并标记其所有倍数。
-
优化:从 i2 开始标记倍数,因为小于 i2 的倍数已经被更小的素数标记过了。
算法复杂度
- 时间复杂度:埃氏筛的时间复杂度为 O(nloglogn),是一种非常高效的素数筛选算法。
- 空间复杂度:需要额外的 O(n) 空间来存储标记数组。
6811

被折叠的 条评论
为什么被折叠?



