标签:
写一个程序,求两个正整数的最大公约数。如果两个正整数都很大,有什么简单的算法吗?
最简单的实现,就是直接用代码来实现辗转相除法。从上面的描述中,我们知道,利用递归就能够很轻松地把这个问题完成。
具体代码如下:
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
标签:
原文地址:http://www.cnblogs.com/gaopeng527/p/4621840.html