求两个数的最大公约数
求两个数的最大公约数有三个方法:
1.辗转相除法;
2.更相减损术;
3.更相减损术与移位相结合;
一.辗转相除法
又名欧几里得算法,目的是求出两个正整数的最大公约数,它是已知的最古老的算法,其可追溯至公元前300年前
这条算法基于一个定理: 两个正整数a和b(a>b),它们的最大公约数等于a除以b的余数c和b之间的最大公约数.
比如10和25,25除以10商2余5,那么10和25的最大公约数,等同于10和5的最大公约数.
//方法入口
public static int getGreatestCommonDivisor(int numberA,int numberB){
int result = 1 ;
if(numberA>numberB){
result=gcd(numberA,numberB);
}else{
result = gcd(numberB,numberA);
}
return result;
}
//递归计算最大公约数
private static int gcd(int a,int b){
if(a%b==0){
return b;
}else{
return (b,a%b);
}
}
二.更相减损术
出自中国古代的《九章算术》,也是一种求最大公约数的算法.
原理:两个正整数a和b(a>b),它们的最大公约数等于a-b的差值c和较小数b的最大公约数.
比如10和25,25减10的差是15,那么10和25的最大公约数,等同于10和15的最大公约数
public static gcd(int numberA,int numberB){
if(numberA==numberB) {
return numberA;
}else if(numberA<numberB){
return gcd(numberB-numberA,numberA);
}else{
return gcd(numberA-numberB,numberB);
}
三.更相减损术和移位法结合
public static int gcd(int numberA,int numberB){
if(numberA==numberB){
return number;
}else if(numberA<numberB){
//保证参数A永远大于B
return gcd(numberB,numberA)
}else{
//和1做按位运算,判断奇偶
if(numberA&1==0&&numberB&1==0){//AB都为偶数
return gcd(numberA>>1,numberB>>1)<<1;
}else if(numberA&1==0&&numberB&1==1){//A为偶数,B为奇数
return gcd(numberA>>1,numberB);
}else if(numberA&1==1&&numberB&1==0){//A为奇数,B为偶数
return gcd(numberA,numberB>>1);
}else{//AB都为奇数,做一次更相减损,使得A-B为偶数
return gcd(numberB,numberA-numberB);
}
}