public class GreatestCommonDivisor {
/**
* 判断最大公约数:
* 1)当a b均为偶数,就求a/2和b/2的最大公约数,再*2
* 2)当a为偶数 b为奇数,就求a/2和b的最大公约数。之所以a/2和b的最大公约数等于a和b的最大公约数,
* 是因为a=2*n1*n2....,b=n1*n2.....(不包括2),因此2一定不会出现在a b的最大公约数(根据质因数分解法,最大公约数为a b的公共系数的乘积)中。
* 2)当a为奇数 b为偶数,就求a和b/2的最大公约数
* 3)当a b均为奇数,就进行更相减损法求解,即求max(a,b)-min(a,b)和min(a,b)的最大公约数,这个最大公约数就是a b的最大公约数。
* 最坏的情况下,需要进行log_2^{max(a,b)}次右移操作,因此时间复杂度为O(logmax(a,b))
* @return
*/
public int gcd(int a, int b){
//求最大公约数的a,b不能为0
if(a==0 || b==0){
return 0;
}
//当a b相等,直接返回a作为公约数
if(a == b){
return a;
}
//如果a b均为偶数
if((a&1)==0 && (b&1)==0){
return gcd(a>>1,b>>1)<<1;
}//如果a为偶数 b为奇数
else if((a&1)==0 && (b&1)!=0) {
return gcd(a>>1,b);
}//如果a为奇数 b为偶数
else if((a&1)!=0 && (b&1)==0){
return gcd(a,b>>1);
}//如果a b均为奇数
else{
return gcd(a>b?a-b:b-a,a<b?a:b);
}
}
}