zoukankan      html  css  js  c++  java
  • 用二进制方法求两个整数的最大公约数(GCD)

    二进制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算法需要用除法,这在某些嵌入式系统中可能排上用场。

    本例实现参考了<<计算机编程的艺术>>第二卷中介绍的算法。

    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));        
            
        }
    }
  • 相关阅读:
    【GC概述以及查看堆内存使用】Java内存管理和GC学习
    Spring的发展【一】
    struts ValueStack 详解
    Mybatis常见面试题(转)
    【Java基础】Java运算符优先级
    【Java基础】基本类型与运算【重要】
    【Java基础】JAVA不可变类(immutable)机制与String的不可变性
    【Java基础】Java基本数据类型与位运算
    【Tomcat】tomcat配置多域名和虚拟路径
    【Tomcat】Tomcat替换猫的图片
  • 原文地址:https://www.cnblogs.com/wushuaiyi/p/3893641.html
Copyright © 2011-2022 走看看