gcd|最大公约数|欧几里得算法|欧几里得算法证明 一文说明白
gcd
最大公因数,也称最大公约数、最大公因子,指两个或多个整数共有约数中最大的一个。a,b的最大公约数记为 $ gcd(a,b) $ ,同样的,a,b,c的最大公约数记为 $ gcd(a,b,c) $ ,多个整数的最大公约数也有同样的记号。
部分选自百度百科
欧几里得算法
欧几里得算法是用来求两个正整数最大公约数的算法。古希腊数学家欧几里得在其著作《The Elements》中最早描述了这种算法,所以被命名为欧几里得算法。
扩展欧几里得算法可用于RSA加密等领域。
假如需要求 1997 和 615 两个正整数的最大公约数,用欧几里得算法,是这样进行的:
1997 ÷ 615 = 3 (余 152)
615 ÷ 152 = 4(余7)
152 ÷ 7 = 21(余5)
7 ÷ 5 = 1 (余2)
5 ÷ 2 = 2 (余1)
2 ÷ 1 = 2 (余0)
至此,最大公约数为1
以除数和余数反复做除法运算,当余数为 0 时,取当前算式除数为最大公约数,所以就得出了 1997 和 615 的最大公约数 1。
部分选自百度百科
欧几里得算法 证明
设有 $ gcd(a,b)=d(a>b) $ ,则 $ d|a $ 、$ d|b $(也就是d既是a的因数也是b的因数)。
设有 $ k=\lfloor\frac{a}{b}\rfloor $ 、 $ r=a \mod b $,则 $ a=bk+r $。
举个栗子,因为 $ a = 5b+1 = 5 \times 2+1 = 11 $ ,则
因为 $ d|b $,所以 $ d|kb $(请感性理解)
因为 $ d|kb+r $ (也就是 $ d|a $ )
所以 $ d|r $ (kb是d的倍数,kb+r也是d的倍数,那么r也就是d的倍数了)
上面整理一下就是 $ d|b $ 且 $ d|r $
所以 $ gcd(b,r)=d $ 了……吗?
并不是,应该是 $ gcd(b,r) \geq d $ (自己可以举个例子)。
我们希望能证明 $ gcd(a,b)=gcd(b,r)=gcd(b,a\mod b) $
所以我们用反证法去证 $ gcd(b,r)>d $ 是不存在的。
反证 $ gcd(b,r)>d $ 是不存在的
设有 $ gcd(b,r)=D>d $,则 $ D|b $ 且 $ D|r $,所以 $ D|kb $。(这里和上面差不多)
因为 $ D|kb $ 而且 $ D|r $,所以 $ D|kb+r $ (转换一下得 $ D|a $ )。现在我们有了 $ D|a $ $ D|b $ ,所以 $ gcd(a,b) \geq D $。
根据最开始说 $ gcd(a,b)=d $ ,所以 $ gcd(a,b)=d \geq D $ ,与 \(D>d\) 矛盾了。
故只有 \(D=d\) 时该假设成立,即 \(gcd(b,r)=d\)
所以\(gcd(a,b)=gcd(b,r)=d\)
化简一下就可以完结撒花: \(gcd(a,b)=gcd(b,a\mod b)\)
……了吗?
我们要设定一个限制条件,即 \(gcd(a,0)=a\)
为什么一定是\(gcd(a,0)=a\)
倒推上去
\(gcd(ak,a)=gcd(a,0)\)
此时ak与a的最大公约数即为a,故\(gcd(a,0)=a\)
最终就有:
欧几里得算法求 gcd 代码
template<typename T>
T gcd(T a,T b){
if(b==0) return a;
return gcd(b,a%b);
}