:: ADVANCE ::

[Algorithm][math] 소수, 에라토스테네스의 체 본문

Algorithm/Algorithm

[Algorithm][math] 소수, 에라토스테네스의 체

KSJ14 2016. 5. 24. 21:34
반응형

[Algorithm][math] 소수, 에라토스테네스의 체



소수 (prime)

약수가 1과 자기 자신 밖에 없는 수  (1은 소수가 아니다)


n이 소수가 되려면, 2보다 크거나 같고, n - 1보다 작거나 같은 자연수로 나누어 떨어지면 안된다.


1
2
3
4
5
6
7
8
9
10
11
bool isprime(int n)
{
    int i;
    
    if(n < 2)    return false;
    
    for(i = 2; i < n; i++)    {
        if(n % i == 0)    return false;
    }
    return true;
}
cs


하지만 이는 n이 클 수록 연산량이 많아 시간이 오래 걸린다.


예를 들어, 문제에서 m개의 수의 소수 판별을 할 필요가 있다면 m번 마다 isprime() 함수를 호출하게 되고 

isprime은 2부터 그 수(n)까지의 반복문을 실행할 것이다.

따라서 연산량이 매우 많다.


매번 수를 소수인지 판별하지 말고

소수를 저장해 놓고 사용하는 것이 더 빠르다.


이러한 경우 에라토스테네스의 체를 이용하여 소수 여부를 한번에 배열에 저장해 놓으면 연산 시간을 줄일 수 있다.



에라토스테네스의 체



* int prime[n] -> 1 : n이 소수, 0 : n은 소수가 아니다.

1. 2부터 n까지 모든 수 배열값은 1로 초기화 해 놓는다.

2. 2부터 i * i <= n 까지 반복

-> i를 root(n)까지 반복

수 n이 소수가 아니라면 n = a x b (a <= b) 이며 a와 b의 가장 차이가 작은 경우는 a == b인 경우이다.

즉, 다시말하면 a의 배수를 검사하는 동안 b의 배수 또한 같이 검사가 되는 것

따라서 가장 차이가 적은 root(n)까지만 검사를 하면 된다.

3. i의 배수를 모두 0으로 고친다.

-> i의 배수는 약수로 i를 가지기 때문에 소수가 아니다.

4. 추가로 i의 배수를 찾아가기 전에 prime 배열의 n값이 이미 소수인지를 판별한다.

-> 소수가 아닌경우 이미 앞에서 배수를 돌면서 i의 배수 또한 0이 되기 때문에 배수를 탐색할 필요가 없다.


* i가 배열의 범위나 자료형의 범위를 넘지 않도록 주의한다.




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int prime[1001];
 
void checkprime()
{
    int i, j;
 
    for (i = 2; i < 1001; i++) {
        prime[i] = 1;
    }
 
    for (i = 2; i * i < 1001; i++) {
        for (j = i; prime[i] && i * j < 1001; j++)
            prime[i * j] = 0;
    }
}
cs



소수 관련 문제

https://www.acmicpc.net/problem/1978

https://www.acmicpc.net/problem/1929

https://www.acmicpc.net/problem/6588

반응형

'Algorithm > Algorithm' 카테고리의 다른 글

[STL] 컨테이너, 반복자  (0) 2016.06.30
[Binary Search] 이진 탐색  (0) 2016.06.24
[Floyd] 플로이드 알고리즘  (0) 2015.10.17
[Heap Sort] 힙 정렬  (0) 2015.07.16
[Quick Sort] 퀵 정렬  (0) 2015.07.15
Comments