inblog logo
|
jjack1
    알고리즘Java

    [JAVA] 8. 필수 알고리즘 Ⅵ. 서로소

    최재원's avatar
    최재원
    Feb 12, 2025
    [JAVA] 8. 필수 알고리즘 Ⅵ. 서로소
    Contents
    1. 두 수의 약수가 1뿐인지 확인2. GCD 최대공약수가 1이라면 두 수는 서로소다.N값 이하의 서로소 개수 구하기1. 전체탐색으로 서로소 개수 구하기2. 공통모듈로 만들자3. 반복문으로 N숫자(12)까지 반복해 보자4. 서로소의 개수를 구해보자 2. 오일러 피함수로 서로소 개수 구하기N값 이하의 서로소 값 찾기1. N이 12인 경우
    ❗
    두 수나 다항식, 집합 등에서 공약수가 1뿐인 경우
    예)
    • 2와 3
    • 9와 10
    • 1과 8
    • 48과 55
    • 연속하는 두 자연수 15, 16
    • 두 연속하는 홀수 3, 5

    1. 두 수의 약수가 1뿐인지 확인

    package algo; // 서로소 // 두 수의 공약수가 1뿐인 경우 public class Coprime01 { public static void main(String[] args) { // 1. 5 와 8은 서로소인가? int a = 5; int b = 8; // 2. a의 약수는? // 1,5 // 3. b의 약수는? // 1,2,4,8 // 4. a의 약수 1, | 5, // b의 약수 1, 2, 4, 8 | 1, 2, 4, 8 // 1 // 공약수는 1뿐 // GCD 최대공약수가 1이라면 서로소인가? // 8 % 5 = 3; // 5 % 3 = 2; // 3 % 2 = 1; // 2 % 1 = 0; } }

    2. GCD 최대공약수가 1이라면 두 수는 서로소다.

    package algo; // 서로소 // 두 수의 공약수가 1뿐인 경우 public class Coprime02 { static int gcd(int n, int m) { return n % m == 0 ? m : gcd(m, n % m); } public static void main(String[] args) { // 5와 8의 최대공약수 구해보기 int n = 5; int m = 8; int a = gcd(n, m); System.out.println(n + "과 " + m + "의 최대공약수: " + a); } }
    notion image

    N값 이하의 서로소 개수 구하기

    ❗
    오일러 피함수
    notion image
    x와 서로소이고 x보다 작은 자연수(음이 아닌 정수)의 개수
    예를 들어 Φ(100)은 다음과 같이 구할 수 있다. 100의 소인수는 2와 5이므로, 아래 공식이 성립한다.
    notion image

    1. 전체탐색으로 서로소 개수 구하기

    1. N이 12라면

    • 1부터 12까지 모든 수를 12와 최대공약수를 비교해 1이면 서로소
    package algo; public class Coprime03 { static int gcd(int a, int b) { return a % b == 0 ? b : gcd(b, a % b); } public static void main(String[] args) { int num = 12; int n = 0; // 전체탐색으로 num이하의 서로소 찾기 // 서로소는 두 수의 최대공약수가 1이면 그 수는 서로소다 // 1일 경우 // 1은 모든 수와 최대 공약수가 1로 같다. // 2일 경우 n = 2; System.out.println(gcd(num, n) == 1 ? n + "은 서로소다" : n); // 3일 경우 n = 3; System.out.println(gcd(num, n) == 1 ? n + "은 서로소다" : n); // 4일 경우 n = 4; System.out.println(gcd(num, n) == 1 ? n + "은 서로소다" : n); // 5일 경우 n = 5; System.out.println(gcd(num, n) == 1 ? n + "은 서로소다" : n); } }
    notion image

    2. 공통모듈로 만들자

    package algo; public class Coprime03 { static int gcd(int a, int b) { return a % b == 0 ? b : gcd(b, a % b); } public static void main(String[] args) { int num = 12; int n = 1; // 전체탐색으로 num이하의 서로소 찾기 // 서로소는 두 수의 최대공약수가 1이면 그 수는 서로소다 // 1일 경우 // 1은 모든 수와 최대 공약수가 1로 같다. // 2일 경우 n++; System.out.println(gcd(num, n) == 1 ? n + "은 서로소다" : n); // 3일 경우 n++; System.out.println(gcd(num, n) == 1 ? n + "은 서로소다" : n); // 4일 경우 n++; System.out.println(gcd(num, n) == 1 ? n + "은 서로소다" : n); // 5일 경우 n++; System.out.println(gcd(num, n) == 1 ? n + "은 서로소다" : n); } }

    3. 반복문으로 N숫자(12)까지 반복해 보자

    package algo; public class Coprime03 { static int gcd(int a, int b) { return a % b == 0 ? b : gcd(b, a % b); } public static void main(String[] args) { int num = 12; int n = 1; // 전체탐색으로 num이하의 서로소 찾기 // 서로소는 두 수의 최대공약수가 1이면 그 수는 서로소다 // 1일 경우 // 1은 모든 수와 최대 공약수가 1로 같다. // 1은 모든 수와 서로소다 // 12-1번 반복 for (int i = 0; i < num - 1; i++) { n++; System.out.println(gcd(num, n) == 1 ? n + "은 서로소다" : n); } } }
    notion image

    4. 서로소의 개수를 구해보자

    package algo; public class Coprime03 { static int gcd(int a, int b) { return a % b == 0 ? b : gcd(b, a % b); } public static void main(String[] args) { int num = 12; int n = 1; int count = 1; // 전체탐색으로 num이하의 서로소 찾기 // 서로소는 두 수의 최대공약수가 1이면 그 수는 서로소다 // 1일 경우 // 1은 모든 수와 최대 공약수가 1로 같다. // 1은 모든 수와 서로소다 // 12-1번 반복 for (int i = 0; i < num - 1; i++) { n++; if (gcd(num, n) == 1) { count++; System.out.println(n + "은 서로소다"); } else { System.out.println(n); } } System.out.println(count + "개"); } }
    notion image

    2. 오일러 피함수로 서로소 개수 구하기

    1. N의 값이 12라면, 12의 약수를 구한다.

    • 12약수는 1~12까지의 수 중 12%n==0을 성립하는 n이다.
    • 1, 2, 3, 4, 6, 12
    package algo; import java.util.ArrayList; import java.util.List; public class Coprime04 { public static void main(String[] args) { // 숫자 1은 제외한다. // 1. 12의 약수 구하기 List<Integer> list = new ArrayList(); int n = 12; for (int i = 2; i <= n; i++) { if (12 % i == 0) { list.add(i); } } System.out.println("1을 제외한 12의 약수들"); System.out.println(list); } }
    notion image

    2. 각 약수들이 소수인지 판별

    • 약수의 개수가 2개면 소수, 1과 자기자신
    package algo; import java.util.ArrayList; import java.util.List; public class Coprime04 { public static void main(String[] args) { // 숫자 1은 제외한다. // 1. 12의 약수 구하기 List<Integer> list = new ArrayList(); int n = 12; for (int i = 2; i <= n; i++) { if (12 % i == 0) { list.add(i); } } // 2. 약수가 소수인지 확인하기 for (int number : list) { int count = 0; for (int i = 1; i <= number; i++) { if (number % i == 0) { count++; } } if (count == 2) { System.out.println(number + "는 소수다"); } } } }
    notion image

    3. 오일러 피함수 공식 사용

    notion image
    package algo; import java.util.ArrayList; import java.util.List; public class Coprime04 { public static void main(String[] args) { // 숫자 1은 제외한다. // 1. 12의 약수 구하기 List<Integer> list = new ArrayList(); int n = 12; for (int i = 2; i <= n; i++) { if (n % i == 0) { list.add(i); } } // 2. 약수가 소수인지 확인하기 List<Integer> sosuList = new ArrayList(); for (int number : list) { int count = 0; for (int i = 1; i <= number; i++) { if (number % i == 0) { count++; } } if (count == 2) { sosuList.add(number); } } // 3. 오일러 피함수 사용하기 double num = 1; for (double number : sosuList) { num *= 1 - (1 / number); } System.out.println((int) (num * n) + "개"); } }
    notion image

    4. 소인수분해를 사용해 오일러 피함수 적용

    package algo; import java.util.ArrayList; import java.util.List; public class Coprime06 { public static void main(String[] args) { // 12를 소인수 분해 int round = 0; int n = 12; int NUMBER = n; int 나누는수 = 2; int 승수 = 0; List<Integer> 나누는수list = new ArrayList<>(); List<Integer> 승수list = new ArrayList<>(); System.out.println("n = " + n); while (true) { round++; if (n % 나누는수 == 0) { n = n / 나누는수; 승수++; } else { if (승수 != 0) { 승수list.add(승수); 나누는수list.add(나누는수); 나누는수 = 나누는수 + (n % 나누는수); 승수 = 0; } else { 나누는수 = 나누는수 + (n % 나누는수); } if (n == 1) break; } } System.out.println("소인수들 = " + 나누는수list); // 소인수를 사용한 오일러 피함수 적용 double num = 1; for (double number : 나누는수list) { num *= 1 - (1 / number); } System.out.println("서로소의 개수 = " + (int) (NUMBER * num) + "개"); System.out.println("반복횟수 = " + round); } }
    notion image

    N값 이하의 서로소 값 찾기

    1. N이 12인 경우

    package algo; import java.util.ArrayList; import java.util.List; public class Coprime05 { static int gcd(int n, int m) { return n % m == 0 ? m : gcd(m, n % m); } public static void main(String[] args) { int n = 12; // 12 이하의 자연수에서 서로소인 값을 찾아보자 List<Integer> 서로소들 = new ArrayList(); for (int i = 1; i <= n; i++) { // 최대공약수가 1이면 서로소다 if (gcd(n, i) == 1) { 서로소들.add(i); } } System.out.println(서로소들); } }
    notion image
     
     
    Share article
    Contents
    1. 두 수의 약수가 1뿐인지 확인2. GCD 최대공약수가 1이라면 두 수는 서로소다.N값 이하의 서로소 개수 구하기1. 전체탐색으로 서로소 개수 구하기2. 공통모듈로 만들자3. 반복문으로 N숫자(12)까지 반복해 보자4. 서로소의 개수를 구해보자 2. 오일러 피함수로 서로소 개수 구하기N값 이하의 서로소 값 찾기1. N이 12인 경우

    jjack1

    RSS·Powered by Inblog