일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- mysql
- 소수
- 그리디
- 웹프로그래밍
- BJ
- 브라우저
- 크루스칼 알고리즘
- request
- 웹 프로그래밍
- DP
- 정렬
- mst
- 벡엔드
- 프림 알고리즘
- greedy
- programmers
- Prim's Algorithm
- 네이버 부스트캠프 ai tech
- 해시
- 웹서버
- 다이나믹 프로그래밍
- 백준
- Kruskal's Algorithm
- jsp
- dbms
- 정렬 알고리즘
- 순열 알고리즘
- 부스트코스
- SERVLET
- 프로그래머스
- Today
- Total
끵뀐꿩긘의 여러가지
Java - 소수 찾기 본문
◎소수의 정의
소수는 자신보다 작은 1 이상의 두 개의 자연수를 곱하여 만들 수 없는 1보다 큰 자연수이다.
ex) 17은 17보다 작은 1이상의 두 개의 자연수를 곱하여 만들 수 없는 수이므로, 소수이다.
=> 즉, 1과 자신만을 약수로 갖는 수이다.
◎소수 판별 알고리즘 1
2부터 판별하는 수 전까지 나눠보고 나머지가 0이 안 나온다면 소수로 정의
public class Main {
public static boolean isPrime(int num){ //num>3
for(int i=2; i<num; i++){ //2~num-1까지 나눈다
if(num % i == 0) return false;
}
return true;
}
}
시간 복잡도: Olog(N)
◎소수 판별 알고리즘 2
소수 판별 알고리즘 1의 주요 골자는 2~num-1까지 중에 num의 약수가 있는지 판별하는 것이다.
그런데, (N>3인 자연수) N의 약수가 가질 수 있는 최솟값이 2이므로, N의 약수가 가질 수 있는 최댓값은 N/2이다.
그러므로, 2~N/2까지 중에 num의 약수가 있는지 판별하면 된다.
시간복잡도: Olog(N/2)
public class Main {
public static boolean isPrime(int num){ //num>3
for(int i=2; i<=num/2; i++){ //2~num/2까지 나눈다
if(num % i == 0) return false;
}
return true;
}
}
여기서 더 발전된 방법으로, (N>3인 자연수) N = sqrt(N)*sqrt(N)이므로, 곱해서 N이 되는 수(약수) 중에 하나는 sqrt(N)보다 크거나 같고 또 다른 하나는 sqrt(N)보다 작거나 같아야 한다.
그러므로, 2~sqrt(N)까지 중에 num의 약수가 있는지 판별하면 된다.
시간 복잡도: Olog(sqrt(N))
public class Main {
public static boolean isPrime(int num){ //num>3
for(int i=2; i*i<=num; i++){ //2~num/2까지 나눈다
if(num % i == 0) return false;
}
return true;
}
}
◎소수 판별 알고리즘 3 : 에라토스테네스의 체
1~N까지의 소수를 모두 구하여야 할 때 사용하는 알고리즘이다.
- 2부터 소수를 구하고자 하는 구간의 모든 수를 나열한다. 그림에서 회색 사각형으로 두른 수들이 여기에 해당한다.
- 2는 소수이므로 오른쪽에 2를 쓴다. (빨간색)
- 자기 자신을 제외한 2의 배수를 모두 지운다.
- 남아있는 수 가운데 3은 소수이므로 오른쪽에 3을 쓴다. (초록색)
- 자기 자신을 제외한 3의 배수를 모두 지운다.
- 남아있는 수 가운데 5는 소수이므로 오른쪽에 5를 쓴다. (파란색)
- 자기 자신을 제외한 5의 배수를 모두 지운다.
- 남아있는 수 가운데 7은 소수이므로 오른쪽에 7을 쓴다. (노란색)
- 자기 자신을 제외한 7의 배수를 모두 지운다.
- 위의 과정을 반복하면 구하는 구간의 모든 소수가 남는다.
만약 2~120까지의 모든 소수를 구하고 싶다면, 소수 판별 알고리즘 2를 활용하여 (int)sqrt(120) +1 = 11까지의 배수만 지우면 남은 모든 수는 소수이다.
import java.util.*;
public class Main {
public static ArrayList<Integer> isPrime(int num){ //num>3
boolean[] SieveofEratosthenes = new boolean[num+1];
SieveofEratosthenes[0] = true;
SieveofEratosthenes[1] = true;
//0,1은 소수가 아니므로 따로 처리
ArrayList<Integer> total = new ArrayList<Integer>();
for(int i=2; (i-1)*(i-1)<=num; i++){
if(SieveofEratosthenes[i]==false){ //false인 수에 도달하면
for(int p = 2; p*i<=num; p++ ){ //그 수의 배수 모두 true처리
SieveofEratosthenes[p*i]=true;
}
}
}
for(int i = 0; i<=num; i++){
if(SieveofEratosthenes[i]==false){
total.add(i);
}
}
return total;
}
public static void main(String[] args) {
ArrayList<Integer> total = isPrime(120);
for(int i = 0; i< total.size(); i++){
System.out.println(total.get(i));
}
}
}
※n의 증가에 따른 공간 복잡도
n이 커지면 커질수록 극심한 차이를 보인다.
'JAVA > 자료구조-알고리즘&함수 정리' 카테고리의 다른 글
Java - 해시(hash)(2/2) (0) | 2021.05.01 |
---|---|
Java - 해시(hash)(1/2) (0) | 2021.05.01 |
Java - 순열 조합 알고리즘 (0) | 2021.04.29 |
Java - HashSet 클래스 (0) | 2021.04.27 |
Java - StringBuilder/StringBuffer 클래스, 메서드 (0) | 2021.04.26 |