第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
原文地址:https://www.cnblogs.com/gaopeng527/p/4621840.html