에라토스테네스의 체는 가장 대표적인 소수 판별 알고리즘이다.
2부터 시작하여 2의 배수를 모두 삭제하고,
3의 배수를 모두 삭제,
(4는 2의 배수이므로 이미 삭제되었으므로), 그다음 5의 배수를 모두 삭제..
이렇게 배수들을 모두 제외시키면서 마지막에는 소수만 남게 되는 알고리즘이다.
function solution(n) {
const sieve = new Array(n + 1).fill(true);
for (let i = 2; i <= n; i++) {
// 이미 지워진 숫자라면 무시한다.
if (sieve[i] === false) continue; // e.g. i = 4 가 나온다면 이미 false 처리 되어있을 것이다.
// 이미 지워진 숫자가 아니라면
for (let j = i + i; j <= n; j += i) { // i의 배수들을 다 지워준다.
sieve[j] = false;
}
}
return sieve.filter((el) => el).length - 2;
}
true
로 채워서 만들어야한다.[true, true, true, true, true, true, true, true, true, true, true]
0 1 2 3 4 5 6 7 8 9 10
i
는 2부터 시작한다.i
의 배수를 모두 삭제해준다.i = 2 일 때,
[true, true, true, true, false, true, false, true, false, true, false]
0 1 2 3 4 5 6 7 8 9 10
i = 4일 때,
i가 이미 false이므로 continue
i = 3 일 때,
[true, true, true, true, false, true, false, true, false, false, false]
0 1 2 3 4 5 6 7 8 9 10
i = 5 일 때,
[true, true, true, true, false, true, false, true, false, false, false]
0 1 2 3 4 5 6 7 8 9 10
i = 7 일 때,
[true, true, true, true, false, true, false, true, false, false, false]
0 1 2 3 4 5 6 7 8 9 10
filter()
메소드를 이용해 값이 true
인 요소들을 필터링하여 개수를 셀 수 있다.배열을 true
로 채우지 않고, 해당 숫자를 값으로 해서 소수 배열을 구할 수도 있다.
function solution(n) {
const sieve = [];
for (let k = 2; k <= n; k++) { // sieve[2] = 2; 이렇게 값 채움
sieve[k] = k;
}
for (let i = 2; i <= n; i++) {
if (sieve[i] === false) continue;
for (let j = i + i; j <= n; j += i) {
sieve[j] = false;
}
}
return sieve.filter((el) => el).length;
}
이렇게 작성하면 n이 10일 때 sieve를 출력했을 때, 아래와 같은 배열을 얻을 수 있다.
[null, null, 2, 3, false, 5, false, 7, false, false, false]
0 1 2 3 4 5 6 7 8 9 10
function solution(n) {
const sieve = [false, false, ...Array(n - 1).fill(true)];
for (let i = 2; i <= n; i++) {
if (sieve[i]) {
for (let j = i * 2; j <= n; j += i) { // sieve에서 i의 2의 배수부터 모든 배수를 모두 false 처리한다.
sieve[j] = false;
}
}
}
return sieve.filter(Boolean).length; // false, 0, -0, 0n, "", null, undefined, NaN은 걸러진다.
}
분명히 봤던 건데... 다시 공부하고 갑니당 !!