# 计算质数(204)
# 题目
# 算法
# 优化的暴力法
暴力法是我们每判断一个数字是不是质数,都从2
到数字-1
整除一遍看看是否有余数,但是这个过程中我们无需全部整除:
- 除了
2
以外其他质数全是奇数 - 我们只需要整除到
x的平方根
,如果从2
到x的平方根
都不能整除,那么x
一定是质数
根据以上两项我们就可以优化暴力法,有几点需要注意:
- 默认
res
为1
,因为我们从3
开始判断,跳过了2
。3
只判断奇数即可,所以每次+2
- 对每一个数字判断的时候,我们除法运算从
3
开始而不是2
,因为我们只判断奇数,一定不能被2
整除;同样,除数我们也每次+2
export const countPrimes = (n) => {
if (n < 3) return 0;
let res = 1;
for (let i = 3; i < n; i += 2) {
let flag = true;
for (let j = 3; j * j <= i; j += 2) {
if (i % j === 0) {
flag = false;
break;
}
}
if (flag) res++;
}
return res;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 埃拉托斯特尼筛法(埃氏筛)
每次判断下一个数字时,我们都将该数字的整数倍数字全部标记为“合数”:
- 先声明一个长度为
n
的数组,用来标记是不是质数
,默认都填充true
- 我们从
2
开始向后依次寻找值为true
的方格(即这个位置的索引值为质数
,即isPrimes[2]
表示数字2
而不是第3
个索引位置) - 如果这个数字
i
的值是true
,那么我们将res++
,并且将其的整数倍数字全部标记为false
,这样以后遍历到这些数字的时候就知道他是合数
埃拉托斯特尼筛法 - 百度百科 (opens new window)
export const countPrimes = (n) => {
const isPrimes = new Array(n).fill(true);
let res = 0;
for (let i = 2; i < n; i++) {
if (isPrimes[i]) {
res++;
for (let j = i + i; j < n; j += i) {
isPrimes[j] = false;
}
}
}
return res;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13