求兩個整數的最大公約數,要盡量優化算法的性能


求兩個整數的最大公約數,要盡量優化算法的性能

 

思路:

  方法一 輾轉相除法, 兩個正整數a,b(a>b), 它們的最大公約數 = a除以b的余數c和較小數b之間的最大公約數。

       例如:10和25, 25除以10=2...5, 那么10和25的最大公約數, 等同於10和余數5的最大公約數。

  方法二:更相減損術 兩個正整數a,b(a>b), 它們的最大公約數 = a-b的差值c和較小數b之間的最大公約數。

      例如:10和25, 25-10=15, 那么10和25的最大公約數, 等同於10和15的最大公約數。

  兩個整數較大時候的場景,取模性能會比較差,更相減損術更適合。但如果兩個數相差懸殊,比如10000和1時,更相減損術就要遞歸9999次。此時可以用方法三

  方法三: 更相減損術+移位(最優):

  1. 當a,b均為偶數時,gcd(a,b) = 2*gcd(a/2,b/2) = 2*gcd(a>>1,b>>1),gcd為方法名;
  2. 當a為偶數,b為奇數時,gcd(a,b) = gcd(a/2,b) = gcd(a>>1,b);
  3. 當a為奇數,b為偶數時,gcd(a,b) = gcd(a,b/2) = gcd(a,b>>1);
  4. 當a,b均為奇數,先使用更相減損術運算一次,gcd(a,b) = gcd(b,a-b),此時a-b必然是偶數,然后又可以繼續進行移位運算 

    ps. >>相當於除以2,<<相當於乘以2

 代碼實現:

/**
 * 求兩個整數的最大公約數,要盡量優化算法的性能
 *
 * 方法一:輾轉相除法, 兩個正整數a,b(a>b), 它們的最大公約數 = a除以b的余數c和較小數b之間的最大公約數。
 *      例如:10和25, 25除以10=2...5, 那么10和25的最大公約數, 等同於10和余數5的最大公約數。
 * 方法二:更相減損術, 兩個正整數a,b(a>b), 它們的最大公約數 = a-b的差值c和較小數b之間的最大公約數。
 *     例如:10和25, 25-10=15, 那么10和25的最大公約數, 等同於10和15的最大公約數
 * 方法三: 更相減損術+移位
 */

public class GreatestCommonDivisor {

    /**
     * 輾轉相除法
     * @param a
     * @param b
     * @return
     */
    public static int getGreatestCommonDivisor(int a, int b){
        int min = a;
        int max = b;
        if ( a >= b ){
            min = b;
            max = a;
        }
        if (min == 0){
            return max;
        }
        int p = max % min;
        return getGreatestCommonDivisor(min,p);
    }

    /**
     * 更相減損術
     * @param a
     * @param b
     * @return
     */
    public static int getGreatestCommonDivisor2(int a, int b){
        int min = a;
        int max = b;
        if ( a >= b ){
            min = b;
            max = a;
        }
        if (min == 0){
            return max;
        }
        int p = max - min;
        return getGreatestCommonDivisor2(min,p);
    }

    /**
     * 更相減損術+移位(最優)
     * @param a
     * @param b
     * @return
     */
    public static int getGreatestCommonDivisor3(int a, int b){
        if(a == b){
            return a;
        }

        if ((a&1)==0 && (b&1)==0){
            return getGreatestCommonDivisor3(a>>1,b>>1)<<1;
        }
        if((a&1)==0 && (b&1)!=0){
            return getGreatestCommonDivisor3(a>>1,b);
        }
        if((a&1)!=0 && (b&1)==0){
            return getGreatestCommonDivisor3(a,b>>1);
        }
        if((a&1)!=0 && (b&1)!=0){
            int min = a > b ? b : a;
            int max = a > b ? a : b;
            return getGreatestCommonDivisor3(min,max-min);
        }


        return 0;
    }

    public static void main (String[] args){
        System.out.println("(1) The Greatest Common Divisor is: " + getGreatestCommonDivisor(24,8));
        System.out.println("(2) The Greatest Common Divisor is: " + getGreatestCommonDivisor2(24,8));
        System.out.println("(3) The Greatest Common Divisor is: " + getGreatestCommonDivisor3(24,8));

    }

}

 結果:

(1) The Greatest Common Divisor is: 8
(2) The Greatest Common Divisor is: 8
(3) The Greatest Common Divisor is: 8


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM