辗转相除法为什么能够得到最大公约数

GCD(Greatest Common Divisor最大公约数)
这里先说一下什么是辗转相除法

辗转相除法的具体内容

两个数求最大公约数

a 45
b 27
ri 表示第 i 次取余的结果

步骤:

  • 用较大数除以较小数,得到余数
    r1 = a % b = 18
  • 取 a、b 中最小的数与 r1相除,得到余数
    r2 = b % r1 = 9
  • 取 r1 与 b中最小的数,与 r2相除,得到余数
    r3 = r1 % r2 = 0
  • 得到 r3 即为最大公约数

简言之就是
先:
r = max % min
再:
max = min
min = r
循环这两步,直到 r = 0

数学原理

number = divisor * coefficient

divisor 代表最大公约数
coefficient 代表系数
reminder 代表余数

假设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 = diviso * 1 = divisor

代码段

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);
	}

}

你可能感兴趣的:(算法分析)