gcd(a,b)表示非负整数a,b的最大公因数,那么:gcd(a,b)=gcd(b,a%b)或者gcd(a,0)=gcd(0,a)=a。
设有两个数num1和num2,假设num1比较大。令余数r = num1 % num2。
当r == 0时,即num1可以被num2整除,显然num2就是这两个数的最大公约数。
当r != 0时,令num1 = num2(除数变被除数),num2 = r(余数变除数),再做 r = num1 % num2。递归,直到r == 0。
int gcd(int a,int b)
{
if(a==0)
return b;
if(b==0)
return a;
return gcd(b,a%b);
}
早在公元前300年左右,
欧几里得
就在他的著作《
几何原本
》中给出了高效的解法——辗转相除法。
辗转相除法
使用到的原理很聪明也很简单,假设用f(x, y)表示x,y的最大
公约数
,取k = x/y,b = x%y,则x = ky + b,如果一个数能够同时
整除
x和y,则必能同时整除b和y;而能够同时整除b和y的数也
必能同时整除x和y,即x和y的公约数与b和y的公约数是相同的,其最大公约数也是相同的,则有f(x, y)= f(y, x % y)(y > 0),如此便可把原问题转化为求两个更
小数
的最大公约数,直到其中一个数为0,剩下的另外一个数就是两者最大的公约数。
特点及意义
最大公约数
指某几个整数共有因子中最大的一个。
GCD即Greatest Common Divisor.
两个整数的最大公约数主要有两种寻找方法:
* 两数各分解质因子,然后取出同样有的项乘起来
* 辗转相除法(扩展版)
和最小公倍数(lcm)的关系:gcd(a, b)×lcm(a, b) = ab
两个整数的最大公因子可用于计算两数的最小公倍数,或分数化简成最简分数。
两个整数的最大公因子和最小公倍数中存在分配律:
* gcd(a, lcm(b, c)) = lcm(gcd(a, b), gcd(a, c))
* lcm(a, gcd(b, c)) = gcd(lcm(a, b), lcm(a, c))
在坐标里,将点(0, 0)和(a, b)连起来,通过整数坐标的点的数目(除了(0, 0)一点之外)就是gcd(a, b)。
gcd递归定理及证明
gcd递归定理是指gcd(a,b)=gcd(b,a%b),其中%表示取余数。
证明如下:
我们只需证明gcd(a,b)和gcd(b,a%b)可以互相整除即可。
对于gcd(a,b),它是a和b的线性组合中的最小正元素,gcd(b,a%b) 是b与a%b的一个线性组合,而a%b是a与b的一个线性组合,因而gcd(b,a%b)是一个a与b的线性组合,因为a,b都能被gcd(a,b)整除,因而任何一个a与b的线性组合都能被gcd(a,b)整除,所以gcd(b,a%b)能被gcd(a,b)整除。反之亦然。