getGreatestCommonDivisor

求两个数的最大公约数

求两个数的最大公约数有三个方法:

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);
        }
}
点赞