[알고리즘] 소수 구하기 _ 에토체

ChoRong0824·2023년 7월 21일
0

Algorithm

목록 보기
19/19
post-thumbnail

소수는 1과 자기자신외에 약수가 존재하지 않는 수입니다.
소수 구하기는 에라토스테네스의 체를 사용합니다.

에라토스테네스의 체 원리

  1. 구하고자 하는 소수의 범위만큼 1차원 배열을 생성
  2. 2부터 시작하고, 현재 숫자가 지워지지 않을 때는 현재 선택된 숫자의 배수에 해당하는 수를 배열에서 끝까지 탐색하면서 지운다.
    --> 이때, 이전에 지워졌던 수, 즉, 처음으로 선택된 수는 지우지 않는다.
  3. 배열의 끝까지 순서 2번을 반복한 후 배열에서 남아있는 모든 수를 출력한다.
  • 위 그림의 코드
ublic int solution(int n) {
    int count = 0;
 
    // n+1 크기 만큼 생성 1부터 n까지의 인덱스로 접근할 수 있음
    int[] nums = new int[n+1];
 
    // 2 번 인덱스부터
    for (int i=2; i<nums.length; i++) {
 
        // 1이면 이미 제외된 숫자
        if (nums[i] == 0) {
            count++;
            for (int j = i; j<nums.length; j+=i) {
                // i의 배수가 1이 아닐 경우만 1로 변경
                if (nums[j] != 1) {
                    nums[j] = 1;
                }
            }
        }
    }
    return count;
}

시간복잡도

이중 for 문을 사용해서, 보통 시간복잡도는 O(N^2)으로 알고 계신분들이 많습니다.
BUt, 실제 시간복잡도는 최적화의 정도에 따라 다르겠지만, 일반적으로 O(Nlog(logN))입니다.
--> 왜? --> 위에 에토체의 원리중 2번을 확인하시면 됩니다.
이전에 지워졌던 수는 지우지 않기 때문에 그만큼 줄어듭니다.

에토체에서, N의 제곱근까지만 탐색하는 이유

N이 ab라고 가정했을 때, a와 b 모두 N의 제곱근보다 클 수 없기 때문입니다.
N = a
b 의 a*b가 루트 N 보다는 절대 클 수 없기 때문입니다.
따라서, N의 제곱근까지만 확인해도 전체 범위의 소수를 판별할 수 있습니다.

코드

자바언어입니다.

import java.util.Arrays;

public class SieveOfEratosthenes {
    public static void main(String[] args) {
        int n = 100; // 찾고자 하는 소수의 범위
        boolean[] primeNumbers = sieveOfEratosthenes(n);

        for (int i = 2; i <= n; i++) {
            if (primeNumbers[i]) {
                System.out.print(i + " ");
            }
        }
    }

    public static boolean[] sieveOfEratosthenes(int n) {
        boolean[] primeNumbers = new boolean[n + 1];
        Arrays.fill(primeNumbers, true);
        primeNumbers[0] = false;
        primeNumbers[1] = false;

        for (int i = 2; i * i <= n; i++) {
            if (primeNumbers[i]) {
                for (int j = i * i; j <= n; j += i) {
                    primeNumbers[j] = false;
                }
            }
        }

        return primeNumbers;
    }
}

이 코드는 sieveOfEratosthenes라는 메서드를 사용하여 에라토스테네스의 체를 구현한 것입니다.
main 메서드에서는 이 방법을 사용하여 2부터 n까지의 소수를 출력하게 됩니다.
여기서 n은 찾고자 하는 소수의 범위로 지정할 수 있습니다.
즉, 위 예제에서는 n을 100으로 설정하여 100 이하의 소수를 찾습니다.

profile
컴퓨터공학과에 재학중이며, 백엔드를 지향하고 있습니다. 많이 부족하지만 열심히 노력해서 실력을 갈고 닦겠습니다. 부족하고 틀린 부분이 있을 수도 있지만 이쁘게 봐주시면 감사하겠습니다. 틀린 부분은 댓글 남겨주시면 제가 따로 학습 및 자료를 찾아봐서 제 것으로 만들도록 하겠습니다. 귀중한 시간 방문해주셔서 감사합니다.

2개의 댓글

comment-user-thumbnail
2023년 7월 21일

시간복잡도에 대한 설명과 에라토스테네스의 체의 원리를 잘 이해할 수 있었습니다. 그리고 소스코드를 통해 더욱 명확하게 이해할 수 있었습니다. 감사합니다.

1개의 답글