Algorithm - Sieve of Eratosthenes
- 2023-10-24 에 풀이한 문제
- 풀이 시간 1 : 10:32 ~ 10:35 ( 타임 리미트 오답 )
- 풀이 시간 2 : 11:35 ~ 11:41 ( 공부 후 다시 풀이 -> 정답 )
- 나의 풀이 깃허브 : 풀이 클릭!
1. 에라토스테네스의 체?
- 에라토스테네스의 체 알고리즘은, 소수를 구하는 알고리즘이다.
public class A { public static int primeNumbers_timeLimitExceeCode(int num) { List<Integer> iList = new ArrayList<>(); for (int i=2; i<=num; i++) { int count = 0; for (int j=2; j<=i; j++ ) { if ( i % j == 0) count ++; if (count >= 2) break; } if (count == 1) iList.add(i); } return iList.size(); } }
- 우리가 소수를 구할 때 해당 코드처럼 2중 루프문을 만들면 시간 복잡도에 걸려 오답처리가 될 가능성이 크다.
- 애초에 소수를 구하는 문제를 물어보면, 그냥 에라토스테네스의 체를 물어보는거라고 생각하면 편하다.
- 에라토스테네스의 체는 “소수가 되는 수의 배수를 지우면 남은 건 소수가 된다” 라고 생각하면 된다.
- 소수가 무엇인지 찾을 필요가 없으며 2부터 자기 자신을 제외한 배수가 되는 것을 지우면 된다.
- 순서는 이러하다.
- 2부터 소수를 구하고자 하는 구간의 모든 수를 나열한다.
- 소수가 되는 수의 배수를 지우면 남은 건은 소수만 된다
- 자기 자신을 제외한 2의 배수를 모두 지운다.
- 남아 있는 수 가운데 3은 소수이므로 오른쪽에 3을 쓴다.
- 자기 자신을 제외한 3의 배수를 모두 지운다.
- 남아 있는 수 가운데 5는 소수이므로 오른쪽에 5를 쓴다.
- 자기 자신을 제외한 5의 배수를 모두 지운다.
- 위 과정을 반복한다.
- 이걸 코드로 구현하면 다음과 같다.
public class A { public static int eratosthenesSieve(int num) { boolean[] isPrime = new boolean[num+1]; Arrays.fill(isPrime, true); isPrime[0] = isPrime[1] = false; for ( int i=2; i*i<=num; i++) { if(isPrime[i]) { for ( int j=i*i; j<=num; j+=i ) { isPrime[j] = false; } } } int answer = 0; for ( boolean tf : isPrime ) { if(tf) answer++; } return answer; } }
- isPrime 이라는 boolean 배열을 만들고, true로 채워준다.
- 이 때 boolean이라는 배열은 우리가 찾으려하는 수보다 +1 만큼 커야한다.
- 그 이유는 boolean[n] 에서 n을 idx 개념이 아닌 숫자 개념으로 볼 것이기 때문이다.
- 0과 1은 소수가 아니므로 boolean[0] 과 boolean[1] 에는 false를 넣어준다.
- 그리고 2부터 루프문을 돌려주면 된다.
- 루프문에서 주의 할 점은 i*i <= num 까지 돌려야 한다는 것이다.
- 이후 true의 개수를 찾아서 반환해주면, 소수의 개수를 알 수 있다.