用二进制方法求两个整数的最大公约数(GCD)
2014-08-06 08:42
260 查看
二进制GCD算法基本原理是:
先用移位的方式对两个数除2,直到两个数不同时为偶数。然后将剩下的偶数(如果有的话)做同样的操作,这样做的原因是如果u和v中u为偶数,v为奇数,则有gcd(u,v)=gcd(u/2,v)。到这时,两个数都是奇数,将两个数相减(因为gcd(u,v) = gcd(u-v,v)),得到的是偶数t,对t也移位直到t为奇数。每次将最大的数用t替换。
二进制GCD算法优点是只需用减法和二进制移位运算,不像Euclid's算法需要用除法,这在某些嵌入式系统中可能排上用场。
本例实现参考了<<计算机编程的艺术>>第二卷中介绍的算法。
先用移位的方式对两个数除2,直到两个数不同时为偶数。然后将剩下的偶数(如果有的话)做同样的操作,这样做的原因是如果u和v中u为偶数,v为奇数,则有gcd(u,v)=gcd(u/2,v)。到这时,两个数都是奇数,将两个数相减(因为gcd(u,v) = gcd(u-v,v)),得到的是偶数t,对t也移位直到t为奇数。每次将最大的数用t替换。
二进制GCD算法优点是只需用减法和二进制移位运算,不像Euclid's算法需要用除法,这在某些嵌入式系统中可能排上用场。
本例实现参考了<<计算机编程的艺术>>第二卷中介绍的算法。
public class GCD_Binary { /** * solve gcd using binary method * @param u * @param v * @return gcd(u,v) */ public static int gcdBinary(int u,int v){ u=(u<0)?-u:u; v=(v<0)?-v:v; if(u==0) return v; if(v==0) return u; int k=0; while((u & 0x01)==0 && (v & 0x01) == 0){ u>>=1; //divide by 2 v>>=1; k++; } //at this time, there is at least one number is odd between m and n int t=-v; //set it negative for later comparison of (t>0) if((v & 0x01)==1){ //v is odd t = u; } //process t as a possible even number while(t != 0){ while((t & 0x01)==0){ //do until t is not even t>>=1; } if(t>0) //u > v (the max is replaced by |t|) u=t; else //u<v (the max is replaced by |t|) v=-t; //now u and v are all odd, then u-v is even t = u-v; } return u*(1<<k); } public static void print(int m,int n,int gcd){ m = (m<0)?-m:m; n = (n<0)?-n:n; System.out.format("gcd of %d and %d is: %d%n",m,n,gcd); } public static void main(String[] args) { int m = -18; int n= 12; print(m,n,gcdBinary(m,n)); //co-prime m = 15; n= 28; print(m,n,gcdBinary(m,n)); m = 6; n= 3; print(m,n,gcdBinary(m,n)); m = 6; n= 3; print(m,n,gcdBinary(m,n)); m = 6; n= 0; print(m,n,gcdBinary(m,n)); m = 0; n= 6; print(m,n,gcdBinary(m,n)); m = 0; n= 0; print(m,n,gcdBinary(m,n)); m = 1; n= 1; print(m,n,gcdBinary(m,n)); m = 3; n= 3; print(m,n,gcdBinary(m,n)); m = 2; n= 2; print(m,n,gcdBinary(m,n)); m = 1; n= 4; print(m,n,gcdBinary(m,n)); m = 4; n= 1; print(m,n,gcdBinary(m,n)); m = 10; n= 14; print(m,n,gcdBinary(m,n)); m = 14; n= 10; print(m,n,gcdBinary(m,n)); m = 10; n= 4; print(m,n,gcdBinary(m,n)); m = 273; n= 24; print(m,n,gcdBinary(m,n)); m = 120; n= 23; print(m,n,gcdBinary(m,n)); } }
相关文章推荐
- 经典算法(3)- 用二进制方法求两个整数的最大公约数(GCD)
- 输入一个整数a,再输入两个整数p1ip2(p1,p2<32),将该整数的二进制表示方法中从右端开始的p1到p2位i
- 1、写一个函数返回参数二进制中 1 的个数(三种方法)2、获取一个数二进制序列中所有的偶数位和奇数位,分别输出二进制序列3、输出一个整数的每一位。4、两个int(32位)整数m和n的二进制表达中,有多
- 2.输入一个整数a,再输入两个整数p1,p2(p1,p2<32),输出该整数的二进制表示方法中从右端开始的p1到p2位.
- 位运算训练03—输入一个整数a,再输入两个整数p1,p2(p1,p2<32);将该整数的二进制表示方法中从右端开始的p1到p2位取反后输出
- 2.2题目:输入一个整数a,再输入两个整数p1,p2(p1,p2<32),输出该整数的二进制表示方法中从右端开始的p1到p2位.
- 输入一个整数a,再输入两个整数p1,p2(p1,p2<32),输出该整数的二进制表示方法中从右端开始的p1到p2位.
- 2.3题目:输入一个整数a,再输入两个整数p1,p2(p1,p2<32),将该整数的二进制表示方法中从右端开始的p1到p2位取反后输出
- 经典算法(2)- 用欧几里得算法求两个整数的最大公约数(GCD)
- Linux_C练习:输入一个整数a,再输入两个整数,输出该整数的二进制表示方法中从右端开始给定位;
- 两个整数交换方法
- 关于交换两个整数的三种方法
- 两个整数交换方法
- 求两个整数的最大公约数和最小公倍数
- 编写两个函数,分别求由键盘输入两个整数的最大公约数和最小公倍数。用主函数调用这两个函数,并输出结果
- C++中几种将整数转换成二进制输出的方法
- 求两个或N个数的最大公约数(gcd)和最小公倍数(lcm)的较优算法
- 将整数转化为二进制,采用递归方法
- 程序员面试100题(算法)之整数的二进制表示中1的个数(两种方法)
- 写两个函数,分别求两个整数的最大公约数和最小公倍数