• 第2章 数字之魅——最大公约数问题


    最大公约数问题

    问题描述

      写一个程序,求两个正整数的最大公约数。如果两个正整数都很大,有什么简单的算法吗?

    分析与解法

    【解法一】

      最简单的实现,就是直接用代码来实现辗转相除法。从上面的描述中,我们知道,利用递归就能够很轻松地把这个问题完成。

      具体代码如下:

     1 package chapter2shuzizhimei.gcd;
     2 /**
     3  * 最大公约数问题
     4  * 【解法一】辗转相除法
     5  * @author DELL
     6  *
     7  */
     8 public class GCD {
     9     //求最大公约数
    10     public static int gcd(int x, int y){
    11         return (y==0)?x:gcd(y,x%y);
    12     }
    13     public static void main(String[] args) {
    14         int x,y;
    15         x = 42;
    16         y = 30;
    17         System.out.println(x+"和"+y+"的最大公约数为:"+gcd(x,y));
    18     }
    19 
    20 }

    程序运行结果如下:

    42和30的最大公约数为:6

    【解法二】

       在解法一中,用到了取模运算。对于大整数而言,取模运算(其中用到除法)是非常昂贵的开销,将成为整个算法的瓶颈。x和y的公约数与x-y和y的公约数是相同的,于是我们可以采用减法。代码如下:

     1 package chapter2shuzizhimei.gcd;
     2 /**
     3  * 最大公约数问题
     4  * 【解法二】递归计算,不用除法,用减法
     5  * @author DELL
     6  *
     7  */
     8 public class GCD2 {
     9     //求最大公约数
    10     public static int gcd(int x, int y){
    11         if(x<y)
    12             return gcd(y,x);
    13         if(y==0)
    14             return x;
    15         else
    16             return gcd(y,x-y);
    17     }
    18     public static void main(String[] args) {
    19         int x,y;
    20         x = 42;
    21         y = 30;
    22         System.out.println(x+"和"+y+"的最大公约数为:"+gcd(x,y));
    23     }
    24 
    25 }

    程序运行结果如下:

    42和30的最大公约数为:6

       这个算法,免去了大整数除法的繁琐,但是同样也有不足之处。最大的瓶颈就是迭代的次数比之前的算法多了不少,如果遇到(10 000 000 000 000,1)这类情况,就会相当令人郁闷了。

     【解法三】

      结合解法一和解法二,分析如下:

     1 package chapter2shuzizhimei.gcd;
     2 /**
     3  * 最大公约数问题
     4  * 【解法三】解法一和解法二的结合
     5  * @author DELL
     6  *
     7  */
     8 public class GCD3 {
     9     public static boolean isEven(int x){
    10         if((x&0x01)==1)
    11             return false;
    12         else
    13             return true;
    14     }
    15     //求最大公约数
    16     public static int gcd(int x, int y){
    17         if(x<y)
    18             return gcd(y,x);
    19         if(y==0)
    20             return x;
    21         else{
    22             if(isEven(x)){
    23                 if(isEven(y))
    24                     return 2*gcd(x>>1,y>>1);
    25                 else
    26                     return gcd(x>>1,y);
    27             }else{
    28                 if(isEven(y))
    29                     return gcd(x,y>>1);
    30                 else
    31                     return gcd(y,x-y);
    32             }
    33         }
    34     }
    35     public static void main(String[] args) {
    36         int x,y;
    37         x = 42;
    38         y = 30;
    39         System.out.println(x+"和"+y+"的最大公约数为:"+gcd(x,y));
    40     }
    41 
    42 }

    程序运行结果如下:

    42和30的最大公约数为:6
  • 相关阅读:
    MYSQL[34]
    MYSQL[32]
    mysql字符集的问题
    MYSQL[31]
    开源RPC框架简介
    MYSQL[35]
    版本号的表示方法
    MYSQL[29]
    MYSQL[39]
    hdu 1166【树状数组】
  • 原文地址:https://www.cnblogs.com/gaopeng527/p/4621840.html
Copyright © 2020-2023  润新知