GCD(Greatest Common Divisor最大公约数)
这里先说一下什么是辗转相除法
辗转相除法的具体内容
GCD(a,b),求a、b的最大公约数
两个数求最大公约数
a | 45 |
---|---|
b | 27 |
ri | 表示第 i 次取余的结果 |
步骤:
- 用较大数除以较小数,得到余数( r1)
r1 = a % b = 18 - 取 a、b 中较小的数(这里是b)与 r1相除( r1一定是 < b 的),得到余数(r2 )
r2 = b % r1 = 9 - 取 r1 与 b中较小的数(这里是 r1),与 r2相除( r1一定是 < r2 的),得到余数( r3 )
r3 = r1 % r2 = 0 - 得到 r3 即为最大公约数
简言之就是
先:
r = max % min
再:
max = min
min = r
循环这两步,直到 r = 0
数学原理(为什么当余数 r = 0,就能得到最大公约数)
number1 = divisor * coefficient1
number2 = divisor * coefficient2
divisor | 代表最大公约数 |
---|---|
coefficient | 代表系数 |
reminder | 代表余数 |
两个数a、b,
a = 最大公约数 x 系数1
b = 最大公约数 x 系数2
假设a = 45, b = 27,求a与b的GCD
a = 45 = 9 * 5 = divisor * m = 最大公约数 * 系数 m
b = 27 = 9 * 3 = divisor * n = 最大公约数 * 系数 n
reminder = a % b = 18 = 9 * ( 5 % 3) = divisor *( m % n ) = divisor * k = 最大公约数 * 系数 k
由reminder = a % b = divisor *( m % n ) 可见,在 a%b的过程中,实际改变的是coefficient(divisor的系数)
所以如果取余到第 n 次时, rn = 0,那么 rn-1 即为最大公约数:
rn = max % min = divisor * ( k % 1 ) = divisor * 0 = 0
max | rn-2 = divisor * k |
---|---|
min | rn-1 = divisor * 1 = divisor |
为什么最后的 rn-1 = divisor * 1(或者说为什么k = 1)
代码段
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class GCD {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String[] split = reader.readLine().split(" ");
int a = Integer.parseInt(split[0]);
int b = Integer.parseInt(split[1]);
// reminder余数
int r = -1;
while (r != 0) {
r = a % b;
a = b;
b = r;
}
System.out.println(a);
}
}