求最大公因数的三种算法及简要说明
1、连续整数法
从给定的最小的数开始按1递减,直至找到一个能被两者都整除的数。
public static int gcd1(int x, int y){
int min = Math.min(x,y);
while (x%min!=0|| y%min!=0){
min--;
}
return min;
}
2、辗转相除法
也叫欧几里得算法,两个整数的最大公约数等于其中较小的那个数和两数相除余数的最大公约数
证明:
假设正整数a>b,有a = kb + r(k,r皆为正整数,且r<b)
假设存在正整数d为a和b的公因数,即d|a,d|b.
而r = a - kb=a mod b,两边同时除以d,r/d=a/d-kb/d=m,由等式右边可知m为整数,
因此d|r
因此d也是b,a mod b的公约数。
因(a,b)和(b,a mod b)的公约数相等,则其最大公约数也相等.QED.
public static int gcd(int m,int n) {
if(m<n) { // guarantee m > n
int k=m;
m=n;
n=k;
}
return m%n == 0?n:gcd(n,m%n);
}
3、更相减损法
两个奇数的最大公约数等于两者之和的一半与两者之差的一半的最大公约数,从而减小两个数之间的差值,直到逼近为一个数,即最大公约数。
证明:gcd(a,b)= gcd ((a+b)/2,(a-b)/2) , a,b都为奇数
设 a = md , b = nd, d = gcd(a,b), m, n, d 都为奇数
(a+b)/2 = (m+n)/2d, (a-b)/2 = (m-n)/2d。两者都为d的整数倍
且倍数不同时为偶数(反证法易证)。QED。
public static int gcd3(int m, int n){
if(m<n) { // guarantee m > n
int k=m;
m=n;
n=k;
}
if(m==n){
return m;
}
if(m%2==0&&n%2==0){
return 2*gcd3(m/2,n/2);
}if(m%2==0){
return gcd3(m/2,n);
}if(n%2==0){
return gcd3(m,n/2);
}else{
return gcd3((m+n)/2,(m-n)/2);
}
}