공부 일지/알고리즘

[알고리즘] 소수 구하기

Joshbla 2022. 6. 25. 11:09

소수(A Prime Number)란? 1과 자기자신 이외의 다른 약수를 가지지 않는 1보다 큰 자연수이다.

 

어떤 수 N이 있을 때 N이 소수인지 아닌지 판별하는 방법을 생각해보자.

N을 2부터 N-1까지 나눠보면서 나머지가 0 이면 중단한다. 

int N;
boolean Prime = true;
for(int i=2; i<N;i++){
	if(N%i==0) {
    		Prime = false;
       	 	break;
        }
}

그러나 이 방법은 시간이 너무 오래걸렸다.

 

그래서 N을 나누는 수가 짝을 이뤄진다는 걸 생각해서 i를 2부터 N의 제곱근까지로 설정해봤다.

int N;
boolean Prime = true;
for(int i=2; i<Math.sqrt(N);i++){
	if(N%i==0) {
    		Prime = false;
       	 	break;
        }
}

그러나 이 방법도 여러가지 수를 구하거나 숫자가 커지면 시간이 오래걸리는 문제가 있었다.

 

그래서 찾아본 결과 '에라토스테네스의 체' 라는 것을 알게되었다.( 참조 블로그 : https://pushback.tistory.com/8 )

방법은 구하고자 하는 최대크기의 N만큼의 boolean 배열을 만들고 전부 true를 넣는다.

0과 1은 소수가 아니므로 false를 넣는다.

그 다음 2부터 해당 숫자가 소수면(true) 그 숫자의 배수를 전부 false로 만든다.

(ex. 2는true 4,6,8,10....은 false 3은 true 6,9,12...는 false)

만약 해당숫자가 소수가 아니면(false) 넘어간다. (4의배수는 이미 2를 계산할 때 모두 false 처리 됐음)

 

int N;
boolean[] Prime = new boolean[N];
Arrays.fill(Prime,true);

Prime[0] = false;
Prime[1] = false;

for(int i=2; i<N;i++){
	if(Prime[i]==true){
        for(int j=i*i ;j<N ;j+=i){
    		Prime[j] = false;
   		}	
	}  
}

 

두번째 for문에서 j가 i*2가 아닌 i*i부터 시작하는 이유는 i*i보다 작은 수는 그 이전 단계에서 이미 처리 됐기때문이다.

(ex. i가 5일 때 5*2 는 이전 단계인 2를 처리할 때 이미 확인, 5*3은 3을 처리할 때 확인, 5*4는 4를처리할때(엄밀히 따지면 2를 처리할 때) 확인 하였음  )

 

 

 

 

[ 알고리즘을 공부한 내용을 정리해보는 공간입니다. 부족한 부분이나 잘못된 부분 지적해주시면 감사하겠습니다.]