강의로 돌아가기
이주홍

[JAVA 풀이 도움 글] 2022-02-18 이전의 질문 글들을 모두 읽고 나름대로 정리해본 글 (필요한 분만 보세용)

아마 일반적인 풀이로는 각 수마다 소수인지 아닌지 판별을 하는 나머지 계산을 하고 여기 오셨을 거라고 생각합니다. 저도 그랬거든요.
2%2 = 0 -> 소수임!
3%2=1 -> 소수 아님
4%2 = 0 -> 1과 자기 자신외의 수로 나뉘어짐 -> 소수 아님
5%2 = 1 -> 불필요한 계산1
5%3 = 1 -> 불필요한 계산2
5%4 = 1 -> 불필요한 계산3
5%5 = 0 -> 소수임!
...
라고 아마 하셨을 겁니다.

위를 보시면 불필요한 계산이 3개 있습니다.
위의 계산이 컴퓨터에서 처리 할때마다 컴퓨터는 %계산을 하게됩니다. -> 시간 증가

[에라토스테네스의 체를 통한 해결방법 정리]
https://ko.wikipedia.org/wiki/%EC%97%90%EB%9D%BC%ED%86%A0%EC%8A%A4%ED%85%8C%EB%84%A4%EC%8A%A4%EC%9D%98_%EC%B2%B4

만약 위 불필요한 계산을 하지않고
배열로 정리하여 모든 수들을 각 방의 번호에 대입합니다. ex)a[0] = 0, a[1] = 1, a[2] = 2 ... a[n] = n
그리고 1은 소수가 아니니 0이라고 정의해봅시다. a[1] = 0
그럼 나머지 방들은 각 방마다 자신의 번호의 수가 있을 겁니다.

조건문으로 만약 방의 값이 0이 아니라면 지속한다고 해봅시다.

2번째 방의 값은 0이 아님 -> 소수이기 때문에 2라고 두고
n범위 까지의 수 범위에서 2의 배수인 수들의 방안의 값을 0이라고 정의합니다 -> (a)
3번째 방의 값은 0이 아님 -> 소수이기 때문에 3이라고 둠
n범위 까지의 수 범위에서 3의 배수인 수들의 방안의 값을 0이라고 정의합니다 -> (b)
4는 (a)에서 0이라고 정의 -> 소수가 아니라고 정의 했기 때문에 넘어갑니다. -> 계산하지 않아도 됨 -> 시간 절약
5번째 방의 값은 0이 아님 -> 소수이기 때문에 5이라고 둠
n범위 까지의 수 범위에서 5의 배수인 수들의 방안의 값을 0이라고 정의합니다
6은 (a),(b)에서 0이라고 정의 -> 소수가 아니라고 정의 했기 때문에 넘어갑니다. -> 계산하지 않아도 됨 -> 시간 절약
7번째 방의 값은 0이 아님 -> 소수이기 때문에 7이라고 둠
n범위 까지의 수 범위에서 7의 배수인 수들의 방안의 값을 0이라고 정의합니다
8은 (a)에서 0이라고 정의 -> 소수가 아니라고 정의 했기 때문에 넘어갑니다. -> 계산하지 않아도 됨 -> 시간 절약
9은 (b)에서 0이라고 정의 -> 소수가 아니라고 정의 했기 때문에 넘어갑니다. -> 계산하지 않아도 됨 -> 시간 절약
10은 (a)에서 0이라고 정의 -> 소수가 아니라고 정의 했기 때문에 넘어갑니다. -> 계산하지 않아도 됨 -> 시간 절약
...
처럼 8,9,10에서 1부터 계산하지 않고도 소수라고 정의할 수 있습니다.

그렇게 되면 주어진 범위 내에서 모든 소수를 찾으셨을텐데
소수가 아닌 수는 0이라고 정의했기 때문에

조건문으로 배열안에 있는 수가 0이 아니라면
answer++
라고 정의해주시고 마지막에 return answer; 라고 해주시면 n의 범위에서 소수의 갯수를 모두 더한 answer값이 제출 될겁니다.

💜💜💜💜💜💜💜💜💜💜💜💜💜💜💜💜
원본 코드의 출처는 deamp9312의 코드입니다.
https://programmers.co.kr/questions/19255
💜💜💜💜💜💜💜💜💜💜💜💜💜💜💜💜

class Solution {
public int solution(int n) {
int answer = 0; // 정답 정의
int[] arr = new int[n+1]; // int타입의 arr은 n+1개의 갯수만큼 int타입으로 공간을 가짐

    // 모든 수를 대입
    for(int i=0;i<=n;i++){  // int타입 i; 0부터 n이하까지 반복; i++
        arr[i]=i;   // arr의 i번째 방은 i이다
    }// 0번째 방은 =1, n-1번째 방은 =n이 된다

    // 1은 소수가 아니라서 0이라고 정의 --> 0이라고 함 
    arr[1]=0;   // arr의 1번째 방은 0

    // 소수 찾기 시작
    for(int i=2;i<=n;i++){//2부터 계산해줌        int타입 i는 2; i가 n이하까지 반복; i++

        // 만약 이전에 찾았던 소수의 배수 값일 경우 계산없이 다음 수로 이동
        if(arr[i]==0)continue;  // arr[i]번째 방이 0이라면 반복문의 처음으로 이동

        // 에라토스테네스의 체를 통해 배수의 수는 소수가 아니라고 정의
        for(int j=i*2;j<=n;j+=i){   // int타입 j가 i*2이고; j가 n이하까지 반복; j = j+i -> 계산을 하지않고 소수가 아닌 값을 찾음
            arr[j]=0;   // arr의 j번째 방은 0 -> 소수가 아니라면
        }
    }

        // 정답 계산
    for(int i=0;i<arr.length;i++){  // int타입 i는 arr의 길이 미만동안 반복 i++
        if(arr[i]!=0){  // arr의 i번째 방이 0이 아니라면 -> 소수
            answer++;   // answer++
        }
    }
    return answer;
}

}

작성중인 코드―Solution.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class Solution {
    public int solution(int n) {
        int answer = 0; // 정답 정의
        int[] arr = new int[n+1];   // int타입의 arr은 n+1개의 갯수만큼 int타입으로 공간을 가짐

        // 모든 수를 대입
        for(int i=0;i<=n;i++){  // int타입 i; 0부터 n이하까지 반복; i++
            arr[i]=i;   // arr의 i번째 방은 i이다
        }// 0번째 방은 =1, n-1번째 방은 =n이 된다

        // 1은 소수가 아니라서 0이라고 정의 --> 0이라고 함 
        arr[1]=0;   // arr의 1번째 방은 0

        // 소수 찾기 시작
        for(int i=2;i<=n;i++){//2부터 계산해줌        int타입 i는 2; i가 n이하까지 반복; i++

            // 만약 이전에 찾았던 소수의 배수 값일 경우 계산없이 다음 수로 이동
            if(arr[i]==0)continue;  // arr[i]번째 방이 0이라면 반복문의 처음으로 이동

            // 에라토스테네스의 체를 통해 배수의 수는 소수가 아니라고 정의
            for(int j=i*2;j<=n;j+=i){   // int타입 j가 i*2이고; j가 n이하까지 반복; j = j+i -> 계산을 하지않고 소수가 아닌 값을 찾음
                arr[j]=0;   // arr의 j번째 방은 0 -> 소수가 아니라면
            }
        }

            // 정답 계산
        for(int i=0;i<arr.length;i++){  // int타입 i는 arr의 길이 미만동안 반복 i++
            if(arr[i]!=0){  // arr의 i번째 방이 0이 아니라면 -> 소수
                answer++;   // answer++
            }
        }
        return answer;
    }
}
  • Tim

    감사합니다

    Tim―2022.10.30 13:49
0 개의 답변
답변 쓰기
이 입력폼은 마크다운 문법을 지원합니다. 마크다운 가이드 를 참고하세요.