辗转相除法
%是求余的意思
抽象例子
比如 a 和 b(a > b)
a % b = r;
如果r 不等于 0
b % r = r1
如果r1 不等于0
r % r1 = r2
如果r2 等于 0
则r1就是最大公约数
如果r2 不等于 0
一直循环到 r_n为0 (r_n 最后一定可以是0,这个很好理解,往下看实例)
最后r_n-1就是最大公约数
具体例子
比如 104 和 40
104 % 40 = 24
40 % 24 = 16
24 % 16 = 8;
16 % 8 = 0;
所以得出104 和 40 的最大公约数就是 8
原理阐述
首先,任何两个数都会有最大公约数 (特殊情况下,最大公约数和最小公约数相等 ,都等于1)
104 和 40 都是「最大公约数」的「倍数」
两个数都是(倍数 X 最大公约数)这样的形式
具体一点就是 k1*c % k2*c = r (c 代表最大公约数 r代表余数 k1、k2代表整数倍)
那么求余的本质是什么?
104 % 40 = 24
就是104 里 包含多少个 整数倍的 40 ,减掉后剩下的余数
所以 104 % 40 = 104 - 2x40 = 24
公式化一点就是,k1*c - k2*c = r (所以 r 也是c的倍数 r = k3*c,因为「c的倍数」- 「c的倍数」依然是「c的倍数」)
然后这个 c 肯定是存在的,如果这个 r = kn*c 中的 kn 为1,那么 r = c 那么就可以求出最大公约数c了
那怎么把 kn 变成1 ????
k1*c - k2*c = r = k3*c
上面公式的本质,可以理解为 k1 % k2 = k3 (k1 > k2 > k3)
如果我们一直拿两个小的不断进行求余,最后的 kn 一定可以是1
为什么kn 最后一定可以是1
比如 13 和 5 的求余
13 % 5 = 3
5 % 3 = 2
3 % 2 = 1
2 %1 = 0
因为 (不断拿两个小的数的)求余过程中两个数会越来越小,肯定会有两个数只相差 1 的情况,也就是说kn一定有可能是1
当余数为0时,说明有数对1进行了求余,此时kn就是1了
所以就有了下面的
104(13 X 8) % 40(5 X 8) = 24(3 X8)
40(5 X 8) % 24(3 X8) = 16(2 X8)
24(3 X8) % 16(2 X8) = 8(1 x 8)
16(2 X8) % 8(1 x 8) = 0(0 X 8)
注意:
我们什么时候知道 r = 1*c ?
做到 24(3 X8) % 16(2 X8) = 8(1 x 8) 时
我们并不知道 8 已经是 (1 X 8)了,
其实我们要多做1步 16(2 X8) % 8(1 x 8) = 0(0 X 8)
当求到余数为0的时候,就说明后面那一个 8一定是(1 X 8)
因为任何数对1求余都会是0
所以 8 就是最大公约数
更相减损术
抽象例子
比如求 a 和 b 之间的最大公约数 (a > b )
a - b = s1 (a >b,a>s1)
分3种情况进行下一步
如果 b > s1
b - s1 = s2 (b > s1.b>s2)
接着重复,将后面两个小的数字相减,
一直到sn为0,sn-1就是最大公约数
如果 b < s1
s1 - b = s2
接着重复,将后面两个小的数字相减,
一直到sn为0,sn-1就是最大公约数
‘如果 b = s1
则最大公约数为s1
具体例子
104 和 40
104 - 40 = 64
64 - 40 = 24
40 - 24 = 16
24 - 16 = 8
16 - 8 = 8
8 - 8 = 0
所以得到 8 就是最大公约数
原理阐述
同样的104 和 40 一定有最大公约数
具体一点就是 k1*c - k2 *c = s (c为最大公约数,k1、k2是整数倍、s是差的结果)
所以s = k3*c (「c的倍数」- 「c的倍数」依然是「c的倍数」)
同样地,我们将kn变成1,最后的 s 就等于 1*c,就是最大公约数
那么如何将kn 变成1 ????
下面就是更相减损的操作
只要我们拿两个小的一直相减,结果kn肯定会有等于1的情况
比如 13 和 5
13 - 5 = 8
8 - 5 = 3
5 - 3 = 2
3 - 2 = 1
2 - 1 = 1
1 - 1 = 0
这个(不断拿两个小的数相减)的过程,实际上就是一种找1的过程
找到最后,一定会出现 2 - 1 = 1,然后 1 -1 =0,这时就找到1了
于是有了下面的
104(13*8) - 40(5*8) = 64(8*8)
64(8*8) - 40(5*8) = 24 (3*8)
40(5*8) - 24(3*8) = 16(2*8)
24(3*8) - 16(2*8) = 8(1*8)
16(2*8) - 8(1*8) = 8(1*8)
8(1*8) - 8(1*8) = 0(0*8)
注意:
我们什么时候能够确定 s = 1*c ?
当kn-1*c - kn*c = 0时, kn-1*c = kn*c
也就是上一个减法已经是2-1 = 1了
到它们相等时,它们不能再往下分了
所以kn-1 = kn = 1
即8(1*8) - 8(1*8) = 0(0*8)
就能确定 8 是最大公约数