소수 구하기 알고리즘 (에라토스테네스의 체 방식)

1 minute read


에라토테네스의 체Permalink

소수를 구하는 방법은 여러가지가 있다. 그중에서도 에라토테네스의 체라는 방법에 대해서 소개해 볼까 한다.

에라토테네스의 체는 대량의 소수를 한번에 구할때 유리하다.

에라토테네스의 기본 아이디어는 배열을 만든 다음 index값을 수 라고 생각한다. 그 다음 소수인 수에 대해서만 체크를 하지 않으면 됩니다.(저의 경우엔 False를 해당 인덱스에 값으로 넣었습니다.)

직접 짠 코드를 보면서 설명하면 좋을 것 같습니다.

전체 코드는 이러합니다. input값으로 주어지는 수는 N>=1 인 자연수로 가정했습니다.

wholelist=[False,False]+[True]*(b-1)

#어떤 값의 약수중 제일 작은 값은 sqrt(N) 보다 같거나 작다.
n=int(b**0.5)+1
for i in range(2,n):
    if (wholelist[i]==True):
        for j in range(2*i,b+1,i):
            wholelist[j]=False





for k in range(a,b+1):
    if wholelist[k]==True:
        print(k)

첫번째 부분입니다.

wholelist=[False,False]+[True]*(b-1)

여기 보면 에라토네스의 체 기본 원리인 배열 생성이 나와 있습니다. 저의 경우 “인덱스”를 기준으로 하여 수를 생각했습니다. 파이썬의 경우 인덱스의 시작은0 이죠. 그래서 첫번째 원소는 무조건 False입니다.

또한 1도 무조건 소수가 아닙니다. 소수의 정의는 여기서 다 하지는 않겠습니다. 2는 무조건 소수입니다. 그래서 True입니다. 2 이상의 수는 일단 무조건 True를 default값으로 저장합니다.


두번째 부분입니다.

#어떤 값의 약수중 제일 작은 값은 sqrt(N) 보다 같거나 작다.
n=int(b**0.5)+1
for i in range(2,n):
    if (wholelist[i]==True):
        for j in range(2*i,b+1,i):
            wholelist[j]=False

여기서 조금 수학이 들어갑니다. 만약 input 값이 합성수 (소수가 아닌 수)이면 약수중 하나는 무조건 n**(1/2) 보다 작거나 같습니다. 따라서 루트 n까지만 약수인지 확인하면 소수임을 증명할 수 있습니다.

이 결과에 때문에 시간 복잡도는 O(n**1/2)이 됩니다. 개이득! 여기서 0.5 제곱해주고 자료형의 반올림 현상때문에 문제가 생길까봐 +1까지 더해줍니다. 그래서 2부터 루트 n까지 돌면서 해당하는 인덱스가 True이면 초기 input값인 b까지 모든 배수들을 True로 바꿔줍니다.


마지막 출력입니다.

for k in range(a,b+1):
    if wholelist[k]==True:
        print(k)

자기가 원하는 구간의 소수를 이러면 다 구할 수 있습니다.

이상 에라토네스의 체에 대한 설명이었습니다.

Leave a comment