Updated:

1. 개요

최대공약수를 구할 때 유클리드 호제법(Euclidean Algorithm)을 이용하면, 모든 정수로 나눠가면 계산할 때 보다 빠른 시간에 최대공약수를 구할 수 있다. 이번에는 유클리드 호제법(Euclidean Algorithm)을 이용하여 최대공약수를 구하는 방법에 대해 알아보도록 하자.

2. 최대공약수(GCD)

두 수의 공약수 중 가장 큰 수를 최대공약수라고 한다.

EX) 9와 18의 최대공약수

  • 9의 약수 = 1, 3, 9

  • 18의 약수 = 1, 2, 3, 6, 9, 18

  • 9와 18의 공약수 = 1, 3, 9

∴ 9와 18의 최대공약수 = 9

3. 최소공배수(LCM)

두 수의 공배수 중 가장 작은 수를 최소공배수라고 한다.

EX) 9와 18의 최소공배수

  • 9의 배수 = 9, 18, 27, …

  • 18의 약수 = 18, 36, 54, …

  • 9와 18의 공배수 = 18, 36, 54, …

∴ 9와 18의 최소공배수 = 18

두 수를 A, B라고 할 때, 아래 공식을 통해 최소공배수를 구할 수 있다.

LCM * GCD = A * B

LCM = A * B / GCD

4. 유클리드 호제법

A를 B로 나눈 나머지를 R이라고 할 때, GCD(B, R)을 계산하며 R이 0이 되었을 때 B의 값이 최대공약수가 된다.

EX) 9와 18의 최대공약수

  • GCD(9, 18)

  • GCD(18, 9)

  • GCD(9, 0)

∴ 9와 18의 최대공약수 = 9

5. 구현 코드

유클리드 호제법은 재귀나 반복문을 사용하여 구현할 수 있다.

5-1. C++

5-1-1. 재귀함수 사용

[소스 코드]

https://github.com/dev-aiden/problem-solving/blob/main/algorithm/euclidean.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>

using namespace std;

int gcd(int a, int b) {
    if (b == 0) return a;
    else return gcd(b, a % b);
}

int lcm(int a, int b) {
    return a * b / gcd(a, b);
}

int main(void) {
    ios_base::sync_with_stdio(false);
    int a, b; cin >> a >> b;
    cout << gcd(a, b) << "\n";
    cout << lcm(a, b) << "\n";
    return 0;
}

[실행 결과]

5-1-2. 반복문 사용

[소스 코드]

https://github.com/dev-aiden/problem-solving/blob/main/algorithm/euclidean2.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>

using namespace std;

int gcd(int a, int b) {
    while (b != 0) {
        int r = a % b;
        a = b;
        b = r;
    }
    return a;
}

int lcm(int a, int b) {
    return a * b / gcd(a, b);
}

int main(void) {
    ios_base::sync_with_stdio(false);
    int a, b; cin >> a >> b;
    cout << gcd(a, b) << "\n";
    cout << lcm(a, b) << "\n";
    return 0;
}

[실행 결과]

5-2. JAVA

5-2-1. 재귀함수 사용

[소스 코드]

https://github.com/dev-aiden/problem-solving/blob/main/algorithm/euclidean.java

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
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Euclidean {

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        int a = Integer.parseInt(st.nextToken());
        int b = Integer.parseInt(st.nextToken());
        System.out.println(gcd(a, b));
        System.out.println(lcm(a, b));
    }

    public static int gcd(int a, int b) {
        if (b == 0) return a;
        else return gcd(b, a % b);
    }

    public static int lcm(int a, int b) {
        return a * b / gcd(a, b);
    }
}

[실행 결과]

5-2-2. 반복문 사용

[소스 코드]

https://github.com/dev-aiden/problem-solving/blob/main/algorithm/euclidean2.java

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
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        int a = Integer.parseInt(st.nextToken());
        int b = Integer.parseInt(st.nextToken());
        System.out.println(gcd(a, b));
        System.out.println(lcm(a, b));
    }

    public static int gcd(int a, int b) {
        while (b != 0) {
            int r = a % b;
            a = b;
            b = r;
        }
        return a;
    }

    public static int lcm(int a, int b) {
        return a * b / gcd(a, b);
    }
}

[실행 결과]

Updated:

Leave a comment