inblog logo
|
sxias
    알고리즘

    [알고리즘] 3. 최대공약수 알고리즘

    문정준's avatar
    문정준
    Feb 07, 2025
    [알고리즘] 3. 최대공약수 알고리즘
    Contents
    최대 공약수문제 분석1. Sampling & Hard Coding결과유클리드 호제법 : 최대공약수를 구할 수 있는 공식문제 재분석1. 코드 작성 : Hard Coding2. Moduling결과Functioning결과최종 코드결과

    최대 공약수

    • 4와 24의 최대 공약수를 구하시오.
     
     

    문제 분석

    • 4의 약수, 24의 약수를 저장해야 함 - 배열 사용
      • 약수를 구하는 방법은 이전 예제에서 참고
    • 각 배열 중 공통된 수만 뽑아서 저장 - 공약수
    • 공통된 수 중 제일 큰 수를 찾기 위해 수를 비교
     

    1. Sampling & Hard Coding

    package algo; public class Gcd { public static void main(String[] args) { // 4와 24의 최대 공약수를 구하시오. // 1. Sampling : 2와 10의 최대 공약수를 구하시오. // 1-1. 2의 약수를 구하시오. (배열 저장) int a = 0; int N1 = 2; int[] d1 = new int[N1]; for (int i = 0; i < N1; i++) { a++; if (N1 % a == 0) { d1[i] = a; System.out.println(N1 + "의 약수 : " + d1[i]); } else { d1[i] = 0; } } // 1-2. 10의 약수를 구하시오. (배열 저장) a = 0; int N2 = 10; int[] d2 = new int[N2]; for (int j = 0; j < N2; j++) { a++; if (N2 % a == 0) { d2[j] = a; System.out.println(N2 + "의 약수 : " + d2[j]); } else { d2[j] = 0; } } // 1-3. 2와 10의 공약수를 구하시오. (배열 내 공통된 수만 저장) // 1-3-1. 두 배열 중 더욱 작은 배열을 찾는다. // N1 < N2 // 1-3-2. 작은 배열의 길이를 저장하고, 반복문을 통해 약수를 비교한다. // 1-3-3. 수가 같으면 배열에 저장한다. int[] d3 = new int[N2]; for (int k = 0; k < N1; k++) { for (int l = 0; l < N2; l++) { int num = d1[k] == d2[l] ? d1[k] : 0; if (num != 0) { d3[k] = num; System.out.println("2와 10의 공약수 : " + d3[k]); } else d3[k] = 0; } } // 1-4. 2와 10의 최대 공약수를 구하시오. (내부에서 제일 큰 수 비교) int result = d3[0]; for (int m = 0; m < N2; m++) { if (d3[m] >= result) { result = d3[m]; } } System.out.println("2와 10의 최대 공약수 : " + result); } }
    ✅
    내가 생각한 코드 분석
    1. 2와 10의 약수를 구하기 위해 반복문 사용, 각각 배열에 저장
      1. NULL 값을 제외하기 위해서 나머지가 안 나오면 0 대입
    1. 2와 10의 공약수를 찾기 위해 이중 반복문 사용
      1. 약수를 서로 인덱스를 통해 비교하고, 같으면 배열에 저장
    1. 공약수 배열에서 내부의 수를 비교하여 결과값 도출
     

    결과

    notion image
     
    ✅
    Trouble Shooting
    Q1. 공약수는 잘 구해졌는데, 최대 공약수가 안 나온 이유?
    • 최댓값을 구하는 방식의 문제?
    Q2. 코드가 너무 길어짐 (BruteForce) : 공식이 필요
     

    유클리드 호제법 : 최대공약수를 구할 수 있는 공식

    • 2개의 자연수 a, b에 대하여 a를 b로 나눈 나머지가 r일 때(a>b일 때), a와 b의 최대공약수는 b와 r의 최대공약수와 같다.
     

    문제 재분석

    • 두 수만 있으면 나머지 연산을 통해 반복문을 사용해서 구할 수 있음
    • 나눌 수 없거나 나머지가 0일 경우 : 더 작은 수가 최대 공약수 (공약수는 더 작은 수의 약수)
     

    1. 코드 작성 : Hard Coding

    package algo; public class Uc { public static void main(String[] args) { // 4와 24의 최대공약수를 구하라. (유클리드 호제법 사용) // 유클리드 호제법 : a와 b (a > b)를 나눈 나머지가 r일 때, 최대공약수는 b와 r의 최대공약수와 같다. // r이 0이거나 더이상 나눌 수 없을 때 (div 0), 더 작은 수 (0 제외)가 최대 공약수이다. // 1. 4와 24의 크기 비교 int a = 4, b = 24; int l = 0; // 큰 수(large) int s = 0; // 작은 수(small) l = a > b ? a : b; s = a < b ? a : b; System.out.println("a, b 중 더 큰 수는 " + l + ", 더 작은 수는 " + s + "입니다."); // 2. a를 b로 나눈 나머지 r을 구하기 int r = l % s; int r2; // 2-1. 나머지가 0일 경우, 최대 공약수는 s if (r == 0) System.out.println("최대 공약수는 " + s); // 2-2. 아닐 경우, b와 r을 나머지 연산을 통해 또 다른 나머지 구하기 // 언제까지? 나머지가 0이 될 때 까지 : 조건반복문 while // 변수 무한정 확장 불가 : 계산되는대로 대입하기, 나머지 변수 초기화 필요 else { while (true) { r2 = s % r; if (r2 == 0) break; s = r; r = r2; r2 = 0; } System.out.println("최대 공약수는 : " + s); } } }
    ✅
    코드 분석
    1. 두 수의 크기 비교 : 삼항연산자 사용
    1. 나머지를 구하고, 나머지가 0이면 최대 공약수 구하기
      1. 아니면, s와 r을 다시 나머지 연산 : while에 포함 가능
     

    2. Moduling

    package algo; public class Uc { public static void main(String[] args) { // 4와 24의 최대공약수를 구하라. (유클리드 호제법 사용) // 유클리드 호제법 : a와 b (a > b)를 나눈 나머지가 r일 때, 최대공약수는 b와 r의 최대공약수와 같다. // r이 0이거나 더이상 나눌 수 없을 때 (div 0), 더 작은 수 (0 제외)가 최대 공약수이다. // 1. 4와 24의 크기 비교 int a = 4, b = 24; int l = 0; // 큰 수(large) int s = 0; // 작은 수(small) int r = 0; l = a > b ? a : b; s = a < b ? a : b; System.out.println("a, b 중 더 큰 수는 " + l + ", 더 작은 수는 " + s + "입니다."); // 2. a를 b로 나눈 나머지 r을 구하기 // r이 0이면 최대 공약수 출력하고 break while (true) { r = l % s; if (r == 0) { System.out.println("최대 공약수는 " + s); break; } l = s; s = r; } } }
     

    결과

    notion image
    notion image
     
     

    Functioning

    package algo; class GCD { int gcd(int a, int b) { int l = 0; // 큰 수(large) int s = 0; // 작은 수(small) int r = 0; l = a > b ? a : b; s = a < b ? a : b; System.out.println("a, b 중 더 큰 수는 " + l + ", 더 작은 수는 " + s + "입니다."); while (true) { r = l % s; if (r == 0) { break; } l = s; s = r; } return s; } } public class Uc { public static void main(String[] args) { // 4와 24의 최대공약수를 구하라. (유클리드 호제법 사용) // 유클리드 호제법 : a와 b (a > b)를 나눈 나머지가 r일 때, 최대공약수는 b와 r의 최대공약수와 같다. // r이 0이거나 더이상 나눌 수 없을 때 (div 0), 더 작은 수 (0 제외)가 최대 공약수이다. // 1. 10과 24의 크기 비교 int x = 10, y = 24; // 2. 클래스 호출 GCD f = new GCD(); // 3. 결과값 출력 = gcd 호출 System.out.println("최대 공약수는 " + f.gcd(x, y)); } }
     

    결과

    notion image
     
    ✅
    Trouble Shooting
    1. 두 수가 서로소일 경우? GCD(x, y) = 1
    1. 6과 0의 최대공약수? : GCD(6, 0) = 6
     

    최종 코드

    package algo; public class Uc { static int gcd(int a, int b) { int l = a > b ? a : b; int s = a < b ? a : b; // System.out.println("a, b 중 더 큰 수는 " + l + ", 더 작은 수는 " + s + "입니다."); // div 0 : 나눌 수 없으므로 l이 최대 공약수 if (s == 0) return l; // 그 외 : 유클리드 호제법 else { // 1. 나머지가 0인 경우 : s를 반환 int r = l % s; if (r == 0) return s; l = s; s = r; // 2. 그 외 : 반복 return gcd(l, s); } } public static void main(String[] args) { // 4와 24의 최대공약수를 구하라. (유클리드 호제법 사용) // 유클리드 호제법 : a와 b (a > b)를 나눈 나머지가 r일 때, 최대공약수는 b와 r의 최대공약수와 같다. // r이 0이거나 더이상 나눌 수 없을 때 (div 0), 더 작은 수 (0 제외)가 최대 공약수이다. // 1. 두 수 대입 int x = 13, y = 17; // 2. 클래스 호출 // 3. 결과값 출력 = gcd 호출 System.out.println("최대 공약수는 " + gcd(x, y)); } }
     

    결과

    1. 두 수가 5, 0일 경우 (div 0)
    notion image
     
    1. 두 수가 서로소일 경우 (13, 17)
    notion image
    1. 일반적인 경우 (4, 24)
    notion image
    Share article
    Contents
    최대 공약수문제 분석1. Sampling & Hard Coding결과유클리드 호제법 : 최대공약수를 구할 수 있는 공식문제 재분석1. 코드 작성 : Hard Coding2. Moduling결과Functioning결과최종 코드결과

    Sxias ㆍ a32176740@gmail.com

    RSS·Powered by Inblog