[20210627] 최대공약수와 최소공배수

유클리드 호제법을 이용하여 최대공약수와 최소공배수를 찾아보자.

기존의 최대공약수 구하는 방법

중등 교육을 받았다면 최대공약수는 누구나 다 구할 수 있을 것이다. 최대공약수는 두 수의 공통된 약수들을 모두 곱한 값이다.

이를 알고리즘으로 풀이해보면,

int a, b; // a, b는 임의의 두 수
int aliquot = 2; // 최소 약수
int gcd = 1;

while(a > 1 || b > 1) {
    if(a % aliquot && b % aliquot) {
        gcd *= aliquot;
        a /= aliquot;
        b /= aliquot;
    } else if(a % aliquot) {
        a /= aliquot;
    } else if(b % aliquot) {
        b /= aliquot;
    } else {
        aliquot++;
    }
}

위의 알고리즘은 약수의 크기가 클 수록 많은 시간이 소모된다. 하지만, 이를 유클리드 호제법을 사용하면 최적화 할 수 있다.

유클리드 호제법을 활용한 최대공약수 구하기

유클리드 호제법은 2개의 자연수 a, b에 대해서 a를 b로 나눈 나머지를 r이라 하면(단, a>b), a와 b의 최대공약수는 b와 r의 최대공약수와 같다는 성질을 이용한 알고리즘이다.

(a, b의 최대공약수) = (b, r의 최대공약수)

이를 코드로 작성하면

 public int gcd(int p, int q) {
    if (q == 0) return p;
    return gcd(q, p%q);
}

굉장히 코드의 양도 줄고 걸리는 시간도 단축된다.

최소 공배수 구하기

(a, b의 최소공배수) = (a, b의 최대공약수(gcd)) x (a / gcd) x (b / gcd)


출처

https://ko.wikipedia.org/wiki/%EC%9C%A0%ED%81%B4%EB%A6%AC%EB%93%9C_%ED%98%B8%EC%A0%9C%EB%B2%95