입력받는 숫자가 소수인지 판별하는 알고리즘 문제를 풀었다.
코드 구현
public static boolean isPrime(int number) {
boolean isPrime = true;
for(int i = 2; i < number; i++) {
if(number % i == 0) {
isPrime = false;
break;
}
}
return isPrime;
}
시간복잡도는 이다.
몇 가지 의문이 생겼다. 2 ~ (number - 1)
까지 다 돌아야 될까? 더 효율적인 방법이 있을까? 라는 고민을 하게 되었다.
라고 한다면, 반드시 를 만족한다.
예시 1
는 3까지만 순환하면 4, 6, 12까지 순환하지 않아도 된다.
예시 2
는 4까지만 순환하면 8, 16까지 순환하지 않아도 된다.
결론적으로 이다.
코드 구현
public static boolean isPrime(int number) {
boolean isPrime = true;
for(int i = 2; i * i <= number; i++) {
if(number % i == 0) {
isPrime = false;
break;
}
}
return isPrime;
}
시간복잡도는 이다.
하지만 대량의 숫자들에 대해 소수 여부를 판별해야 할 때에는 제곱근 나누기 방법보다는 다음에 소개할 에라토스테네스의 체 방법을 사용한다. 제곱근 나누기 방법은 모든 숫자를 판별해야 되지만 에라토스테네스의 체는 앞에서 구한 소수의 배수를 이용하여 미리 판별할 수 있다.
다음은 에라토스테네스의 체 알고리즘이다.
코드 구현
public static void eratos(int number) {
boolean[] isPrimes = new boolean[number + 1];
Arrays.fill(isPrimes, true);
for (int i = 2; i * i <= number; i++) {
if(!isPrimes[i]) {
continue;
}
for (int j = i * i; j <= number; j+=i) {
isPrimes[j] = false;
}
}
for (int i = 2; i <= number; i++) {
if (isPrimes[i]) {
System.out.println(i);
}
}
}
시간복잡도는 이다.