/***
* 问题:写一段代码,求出两个整数的最大公约数,尽量优化算法的性能
*/
public class getGreatestCommonDivision {
/**
* 辗转相除法,又名欧几里得算法
* 定理:两个正整数a和b(a>b),
* 他们的最大公约数等于a除以b的余数c和b之间的最大公约数
* @param a
* @param b
* @return
*/
public static int getGreatestCommonDivisionV2(int a,int b)
{
int big=a>b?a:b;
int small=a<b?a:b;
if(big%small==0)
return small;
return getGreatestCommonDivisionV2(big%small,small);
}
/**
* 更相减损术
* 两个正整数a和b(a>b),它们的最大公约数等于a-b的差值c和较小数b的最大公约数
* @param a
* @param b
* @return
*/
public static int getGreatestCommonDivisionV3(int a,int b)
{
int big=a>b?a:b;
int small=a<b?a:b;
if(big==small)
return small;
return getGreatestCommonDivisionV3(big-small,small);
}
/***
* 把辗转相除法和更相减损术的优势结合起来,在更相减损术的基础上使用移位运算
* 算法思想:
* 当a和b均为偶数时 gcd(a,b)=2*gcd(a/2,b/2)=gcd(a>>1,b>>1)<<1
* 当a为偶数,b为奇数时,gcd(a,b)=gcd(a/2,b)=gcd(a>>1,b);
* 当a为奇数,b为偶数时,gcd(a,b)=gcd(a,b/2)=gcd(a,b>>1);
* 当a,b都为奇数时,假设a>b时,gcd=(a,b)=gcd(a-b,b);此时a-b必然为偶数;
* @param a
* @param b
* @return
*/
public static int gcd(int a,int b)
{
if(a==b)
return a;
if((a&1)==0&&(b&1)==0)
return gcd(a>>1,b>>1)<<1;
else if((a&1)==0&&(b&1)==1)
return gcd(a>>1,b);
else if((a&1)==1&&(b&1)==0)
return gcd(a,b>>1);
else {
int big = a > b ? a : b;
int small=a<b?a:b;
return gcd(big - small, small);
}
}
public static void main(String[] args) {
System.out.println(gcd(25,5));
System.out.println(gcd(100,80));
System.out.println(gcd(27,14));
}
}
求两个整数的最大公约数(算法学习)
最新推荐文章于 2022-11-09 22:06:58 发布