해당 수가 소수인지 아닌지 반복문을 돌려서 구할 수도 있지만, 효율성이 많이 떨어진다.
특히 특정 범위에서 소수를 모두 구해야 하는 경우는 해당 범위 * 범위에 속한 수의 크기만큼 반복문을 돌려야하기 때문에 매우 비효율적이다.
function isPrime(number) {
if(number === 1) return false;
for(let i = 2; i < number; i++) {
if(Math.floor(number/i) === number/i) return false;
}
return true;
}
function solution(n) {
let answer = 0;
for(let i = 1; i <= n; i++) {
if(isPrime(i)) answer++;
}
return answer;
}
- 좋지 않은 예시
효율적으로 특정 범위에 있는 모든 소수를 구할 때 사용되는 알고리즘이 바로 에라토스테네스의 체이다.
에라토스테네스의 체는, 소수의 배수들을 차례대로 지워나가면서 효율적으로 소수만 구할 수 있는 알고리즘이다.
만약 1부터 n까지의 범위에 있는 수 중 소수를 모두 구하려면,
- 크기가 n+1인 배열 생성
- index 와 수를 일치시키기 위해 n+1 크기로 배열을 생성한다.
- 생성한 배열의 기본값을 모두 1로 채운다.
- index 0과 index 1의 값은 0으로 설정한다. (index 0은 사용하지 않으므로 제외, 1은 소수가 아니므로 index 1 제외)
let numbers = new Array(n+1).fill(1); numbers[0] = numbers[1] = 0;
- 소수의 배수 제거
- 소수(요소가 1인 index)를 찾아 해당 소수의 배수를 모두 0으로 바꾼다.
- 배수를 제거하기 위해 소수를 선택하는 작업은 n의 제곱근까지만 진행한다.
> n의 제곱근보다 큰 수 중 소수가 아닌 수는 다른 수의 배수로 제거된다.
- 특정 소수의 배수를 제거하는 작업은 해당 소수의 제곱부터 시작한다.
> 해당 소수의 제곱 미만의 배수들은 이미 이전에 처리된 소수의 배수에 의해 제거되었다.
ex) 3의 배수를 찾을 때, 3*2, 3*3, 3*4 .... 순서로 배수를 찾게 되는데, 3*2=6은 이미 2*3으로 제거되었다.
for (let i = 2; i <= Math.sqrt(n); i++) { if (!!numbers[i]) { for (let j = i*i; j <= n; j += i) { numbers[j] = 0; } } }
- 소수 찾기
- 값이 1인 요소의 index를 찾으면 된다.
- 개수를 구할 경우 1의 개수를 구한다.
//모든 소수 let answer = []; for(let i = 2; i <= n; i++) { if(numbers[i]) answer.push(i); } return answer; //개수 let cnt = 0; for(let num of numbers) { if(num) cnt++; } return cnt;
'클라이언트 > JavaScript' 카테고리의 다른 글
[자바스크립트(JavaScript)] Million.js (0) | 2024.02.06 |
---|---|
[자바스크립트(JavaScript)] 특정 범위에서 약수의 개수 구하기(에라토스테네스의 체) (0) | 2024.01.11 |
[자바스크립트(JavaScript)] Builder 패턴 (0) | 2023.12.18 |
[자바스크립트(JavaScript)] Audio (0) | 2023.12.16 |
[자바스크립트(JavaScript)] 정규식 (Test, Match) (0) | 2023.12.15 |