[알고리즘] 소수(에라토스테네스 체)
(문제) 소수(에라토스테네스 체)
자연수 N이 입력되면 1부터 N까지의 소수의 개수를 출력하는 프로그램을 작성하세요.
만약 20이 입력되면 1부터 20까지의 소수는 2, 3, 5, 7, 11, 13, 17, 19로 총 8개입니다.
제한시간은 1초입니다.
입력설명
첫 줄에 자연수의 개수 N(2<=N<=200,000)이 주어집니다.
출력설명
첫 줄에 소수의 개수를 출력합니다.
테스트케이스
입력예제 | 출력예제 |
---|---|
20 | 8 |
2 | 1 |
200000 | 17984 |
150000 | 13848 |
90000 | 8713 |
100000 | 9592 |
해결방법
N + 1개 만큼의 0으로 초기화 된 리스트를 생성한다.
(N+1 인 이유는 0부터 인덱스를 생각하지 않고 1부터 생각하기 위함)
2중 반복문 + 초기 리스트 이용
큰 반복문을 2에서 N+1 번 반복한다.
만약 반복문을 진행할때 그 부분이 0 이면 소수이므로 count + 1 하여 소수라고 나타내는 변수에 나타낸다.
큰 반복문 에서 받은 값을 시작으로 작은 반복문을 생성하여 그 값만큼 배수로 껑충 껑충 뛴다.
그림의 경우, 11의 제곱>120 이므로 11보다 작은 수의 배수들만 지워도 충분하다.
이유는 2에서부터 배수로 확인을 한다. 그러면 2 * 1, 2 * 2, 2 * 3, 2 * 5 …. 처럼 확인을 하는데,
만약 다음 3에서 배수로 확인을 할 때, 이전에 2에서 이미 2 * 3을 했으니 3 * 3 부터 확인을 하면 된다. 3 * 3, 3 * 4, 3 * 5 …
다음 4는 이미 2를 가지고 있는 배수여서 넘어가고 5에서는 이미 뒤에, 2, 3 을 확인 했으니 5 * 5 부터 5 * 6 … 이런 식으로 확인하면 된다.
즉, 120보다 작거나 같은 수 가운데 2, 3, 5, 7의 배수를 지우고 남는 수는 모두 소수이다.
코드 방법 1 (2부터 n까지의 순회)
# n까지의 소수의 개수를 구하기
n = int(input())
# 에라토스테너스의 체는 리스트 하나를 생성한다
n_arr = [0] * (n + 1)
# 소수 개수 세기
count = 0
# 2~20 까지 반복 소수의 시작은 2부터 이므로
for i in range(2, n+1):
# 소수가 아니면 1
# 맨처음에 소수인지 확인한다 (소수 시작 2)
# 소수는 0
if n_arr[i] == 0:
count = count + 1
# 배수로 돌음
# 해당 소수를 찾으면 그것을 이용하여 반복문을 그 소수의 배수로 돈다
for j in range(i, n+1, i):
# 첫번째는 빼고 다 1로
n_arr[j] = 1
print(count)
코드 방법 2 (2부터 int(n**0.5)+1까지의 순회)
# n까지의 소수의 개수를 구하기
n = int(input())
# 에라토스테너스의 체는 리스트 하나를 생성한다
n_arr = [0] * (n + 1)
count = 0
for i in range(2, int(n**0.5)+1):
# 소수이다
if n_arr[i] == 0:
for j in range(i*2, n+1, i):
# 체크를 했고, 또한 배수가 되는 것들 소수가 아니다
n_arr[j] = 1
print(len([i for i in range(2, len(n_arr)) if n_arr[i] == False]))
댓글남기기