> 기초/알고리즘
TIL-2024.02.24 - 알고리즘 - 소수 구하기 (반복문 & 에라토스테네스의 체)
Janku
2024. 2. 24. 18:27
------- 소수
정의:
- 소수는 1보다 큰 자연수 중 1과 자기 자신만을 약수로 가지는 수이다.
판별 알고리즘:
- 반복문
- 에레토스테네스의 체
기본 알고리즘:
1. 반복문(시간 복잡도 O(n))
const isPrime = (num) => {
for(let i = 2; i < num ; i++){
if(num % i) return false; // num이 다른 수로 나눠떨어지면 소수가 아님.
}
return true;
}
2. 반복문(num / 2 - 시간 복잡도 O(n))
만약 어떤 수 n이 n/2보다 큰 약수를 가진다면, 그러한 약수는 n/2보다 작은 수의 곱으로 이미 나타낼 수 있습니다
const isPrime = (num) => {
for(let i = 2; i < num/2 ; i++){
if(num % i) return false; // num이 다른 수로 나눠떨어지면 소수가 아님.
}
return true;
}
3. 반복문( num 제곱근- 시간 복잡도 O(n))
만약 어떤 수 n이 sqrt(n)보다 큰 약수를 가진다면, 그러한 약수는 sqrt(n)보다 작은 수의 곱으로 이미 나타낼 수 있습니다
const isPrime = (num) => {
for(let i = 2; i < parseInt(Math.sqrt(num) ; i++){
if(num % i) return false; // num이 다른 수로 나눠떨어지면 소수가 아님.
}
return true;
}
에라토스테네스의 체:
기본 알고리즘:
- 2부터 소수를 구하고자 하는 구간의 모든 수를 나열한다. 그림에서 회색 사각형으로 두른 수들이 여기에 해당한다.
- 2는 소수이므로 오른쪽에 2를 쓴다. (빨간색)
- 자기 자신을 제외한 2의 배수를 모두 지운다.
- 남아있는 수 가운데 3은 소수이므로 오른쪽에 3을 쓴다. (초록색)
- 자기 자신을 제외한 3의 배수를 모두 지운다.
- 남아있는 수 가운데 5는 소수이므로 오른쪽에 5를 쓴다. (파란색)
- 자기 자신을 제외한 5의 배수를 모두 지운다.
- 남아있는 수 가운데 7은 소수이므로 오른쪽에 7을 쓴다. (노란색)
- 자기 자신을 제외한 7의 배수를 모두 지운다.
- 위의 과정을 반복하면 구하는 구간의 모든 소수가 남는다.
코드:
const solution = (n) => {
// 주어진 수가 2 미만이면 소수가 없으므로 0 반환
if (n < 2) return 0;
// 소수 판별을 위한 배열 생성 및 초기화 >
// 소수를 판별하기 위한 배열을 생성하고, 모든 수를 일단 소수로 가정하여 true로 초기화합니다. 그러나 0과 1은 소수가 아니므로 false로 값을 변경합니다.
let primes = new Array(n + 1).fill(true);
// console.log(1, primes) // [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
primes[0] = primes[1] = false; // 0과 1은 소수가 아니므로 false로 초기화
// 에라토스테네스의 체 알고리즘을 사용하여 소수 찾기
// 에라토스테네스의 체 알고리즘을 사용하여 소수를 찾습니다. 먼저 2부터 시작하여 해당 수가 소수인 경우,
// 그의 배수들을 모두 소수가 아니라고 표시합니다. 이는 소수의 배수들을 걸러내는 것으로, 비효율적인 반복을 줄여줍니다.
// n의 제곱근 사용 이유: 만약 어떤 수 n이 sqrt(n)보다 큰 약수를 가진다면, 그러한 약수는 sqrt(n)보다 작은 수의 곱으로 이미 나타낼 수 있습니다
for (let i = 2; i <= Math.sqrt(n); i++) {
if (primes[i]) {
// 현재 숫자가 소수인 경우, 그의 배수들을 모두 소수가 아니라고 표시
for (let j = i * i; j <= n; j += i) {
console.log(`i is ${i}`)
console.log(`j is ${j}`) // 현재 값
console.log(`next is ${j += i}`) // 2의 배수
primes[j] = false;
}
}
}
// 소수인 수의 개수 카운트
// 소수인 수의 개수를 세기 위해 primes 배열에서 true로 남아있는 수들의 개수를 세어줍니다.
let count = 0;
for (let i = 2; i <= n; i++) {
if (primes[i]) count++;
}
return count;
};