[Java] BOJ 4134: 에라토스테네스의 체

2025. 2. 4. 02:04·Engineering Notes/CS & Algorithms

소수 검증

static boolean isPrimeNumber(int n) {
    if (n < 2) {
        return false;
    }
    for (int divisor = 2; divisor <= Math.sqrt(n); divisor++) {
        if (n % divisor == 0) {
            return false;
        }
    } return true;
}

▶ 특정 숫자가 소수인지를 판단할 때, 우리는 해당 숫자의 제곱근까지만 약수 여부를 검증하면 된다. 그런데 만약, 범위 내의 소수를 모두 알고 싶다면 어떻게 해야 할까?


범위 내 소수 검증

public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    
    int start = sc.nextInt();
    int end = sc.nextInt();

    for (int i = start; i <= end; i++) {
        if (isPrimeNumber(i)) {
            System.out.println(i);
        }
    }
}

// 소수 검증 메서드
static boolean isPrimeNumber(int n) {
    if (n < 2) {
        return false;
    }
    for (int divisor = 2; divisor <= Math.sqrt(n); divisor++) {
        if (n % divisor == 0) {
            return false;
        }
    } return true;
}

▶ 앞서 제시한 메서드를 사용하면, 당연히 반복문을 통해 범위 내 소수를 나열할 수 있다. 하지만 입력된 범위가 커지면 커질수록 더 많은 연산이 필요하기 때문에 성능 측면에서 비효율적이다. 에라토스테네스의 체를 사용하여 성능을 개선해 보자.


에라토스테네스의 체

public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);

    int start= sc.nextInt();
    int end = sc.nextInt();
    int[] nums = new int[end + 1];

    for (int i = 2; i <= end; i++) {
        nums[i] = i;
    }

    // 에라토스테네스의 체
    for (int i = 2; i <= Math.sqrt(end); i++) {
        if (nums[i] == 0) {
            continue;
        }
        for (int j = i * i; j <= end; j += i) {
            nums[j] = 0;
        }
    }

    for (int i = start; i <= end; i++) {
        if (nums[i] != 0) {
            System.out.println(nums[i]);
        }
    }
}

[코드 분석]

int[] nums = new int[end + 1]

▶ 0번 인덱스을 고려해 배열의 크기를 1 늘려 선언한다.

for (int i = 2; i <= end; i++) {
    nums[i] = i;
}

▶ 2번 인덱스부터 값을 넣어줌으로써, 1은 자연스럽게 소수에서 제외한다.


for (int i = 2; i <= Math.sqrt(end); i++) {...}

▶ 검증에 필요한 수는 마지막 숫자의 제곱근까지다.

if (nums[i] == 0) {
    continue;
}

▶ 이미 지워진 숫자는 건너뛴다.

for (int j = i * i; j <= end; j += i) {...}

▶ j = i * i로 하는 이유는 i보다 작은 배수들은 이미 제거된 상태이기 때문이다.


for (int i = start; i <= end; i++) {
    if (nums[i] != 0) {
        System.out.println(nums[i]);
    }
}

▶ 입력된 범위 내 소수를 출력한다.

'Engineering Notes > CS & Algorithms' 카테고리의 다른 글

그래프 탐색 알고리즘 BFS 풀이  (0) 2025.02.27
[Java] BOJ 11866: 요세푸스 문제, 큐  (1) 2025.02.05
[Java] BOJ 10814: 나이순 정렬, 2차원 배열  (4) 2025.01.22
[Java] BOJ 11650: 람다 표현식, 정렬 조건 부여하기  (3) 2025.01.16
[Java] BOJ 2609: 유클리드 호제법, 기약분수 만들기  (6) 2025.01.15
'Engineering Notes/CS & Algorithms' 카테고리의 다른 글
  • 그래프 탐색 알고리즘 BFS 풀이
  • [Java] BOJ 11866: 요세푸스 문제, 큐
  • [Java] BOJ 10814: 나이순 정렬, 2차원 배열
  • [Java] BOJ 11650: 람다 표현식, 정렬 조건 부여하기
UTACT
UTACT
시작은 가볍게 이유는 무겁게
  • UTACT
    Software Engineer
    UTACT
    • GitHub
  • 전체
    오늘
    어제
  • 공지사항

    • README
  • 최근 글

    • 분류 전체보기 (126)
      • Project Logs (2)
        • DashHub (2)
        • Re:Act (0)
        • Samsung NW (0)
      • Engineering Notes (76)
        • Java & Spring (44)
        • Database & Persistence (1)
        • DevOps & Infra (4)
        • CS & Algorithms (26)
        • Security (1)
      • Reflections (5)
        • Retrospectives (1)
        • Feedback Received (3)
        • Challenges (1)
      • Tips (24)
      • Archive (19)
  • 태그

    Data Type
    REST
    BFS
    iamdefinitelyabackenddeveloper
    데이터 영속성
    토스페이먼츠
    인접 노드 리스트
    JPA
    vite
    .prettierrc
    heapify
    타입 소거
    VS Code
    OOP
    IntelliJ
    cherry-pick
    where-was-i
    Array
    BOJ
    도커
    CS
    팀 정렬
    Reallocation
    heap
    @CreatedDate
    hate-cnu
    버프 슈트
    듀얼 피봇 퀵 정렬
    Python
    DS
  • hELLO· Designed By정상우.v4.10.6
UTACT
[Java] BOJ 4134: 에라토스테네스의 체
상단으로

티스토리툴바