代码之家  ›  专栏  ›  技术社区  ›  Albert

获取最大公约数

  •  74
  • Albert  · 技术社区  · 14 年前

    我已经看到这样一个函数存在于 BigInteger BigInteger#gcd . 在Java中还有其他功能,它也适用于其他类型吗? int , long Integer )?这似乎是有道理的 java.lang.Math.gcd (有各种过载)但它不在那里。它在别的地方吗?


    (请不要将这个问题与“我如何自己实现这个”混淆!)

    16 回复  |  直到 6 年前
        1
  •  67
  •   Ry- Vincenzo Alcamo    6 年前

    对于int和long,作为原语,不是真的。对于整数,可能有人写了一个。

    假设biginteger是int、integer、long和long的(数学/函数)超集,如果需要使用这些类型,请将它们转换为biginteger,执行gcd,然后将结果转换回。

    private static int gcdThing(int a, int b) {
        BigInteger b1 = BigInteger.valueOf(a);
        BigInteger b2 = BigInteger.valueOf(b);
        BigInteger gcd = b1.gcd(b2);
        return gcd.intValue();
    }
    
        2
  •  124
  •   Jon Egeland    12 年前

    据我所知,没有任何内置的原语方法。但是像这样简单的事情应该可以做到:

    public int GCD(int a, int b) {
       if (b==0) return a;
       return GCD(b,a%b);
    }
    

    如果你对这类事情感兴趣,你也可以只写一行:

    public int GCD(int a, int b) { return b==0 ? a : GCD(b, a%b); }
    

    应该注意的是 两者编译为相同字节代码时的差异。

        3
  •  33
  •   Xorlev    14 年前

    或欧几里得算法计算的GCD…

    public int egcd(int a, int b) {
        if (a == 0)
            return b;
    
        while (b != 0) {
            if (a > b)
                a = a - b;
            else
                b = b - a;
        }
    
        return a;
    }
    
        4
  •  11
  •   Morad    10 年前
        5
  •  11
  •   Robot Monk    9 年前

    雅加达公共数学就是这样。

    ArithmeticUtils.gcd(int p, int q)

        6
  •  9
  •   Alexey    8 年前

    除非我有番石榴,我定义如下:

    int gcd(int a, int b) {
      return a == 0 ? b : gcd(b % a, a);
    }
    
        7
  •  6
  •   linuxjava    10 年前

    您可以使用 Binary GCD algorithm

    public class BinaryGCD {
    
    public static int gcd(int p, int q) {
        if (q == 0) return p;
        if (p == 0) return q;
    
        // p and q even
        if ((p & 1) == 0 && (q & 1) == 0) return gcd(p >> 1, q >> 1) << 1;
    
        // p is even, q is odd
        else if ((p & 1) == 0) return gcd(p >> 1, q);
    
        // p is odd, q is even
        else if ((q & 1) == 0) return gcd(p, q >> 1);
    
        // p and q odd, p >= q
        else if (p >= q) return gcd((p-q) >> 1, q);
    
        // p and q odd, p < q
        else return gcd(p, (q-p) >> 1);
    }
    
    public static void main(String[] args) {
        int p = Integer.parseInt(args[0]);
        int q = Integer.parseInt(args[1]);
        System.out.println("gcd(" + p + ", " + q + ") = " + gcd(p, q));
    }
    

    }

    http://introcs.cs.princeton.edu/java/23recursion/BinaryGCD.java.html

        8
  •  6
  •   Robot Monk    9 年前

    如果两个数字都为负数,则此处的某些实现无法正常工作。GCD(-12,-18)是6,而不是-6。

    所以应该返回一个绝对值,比如

    public static int gcd(int a, int b) {
        if (b == 0) {
            return Math.abs(a);
        }
        return gcd(b, a % b);
    }
    
        9
  •  3
  •   Alfabravo    6 年前

    我们可以使用递归函数来查找gcd

    public class Test
    {
     static int gcd(int a, int b)
        {
            // Everything divides 0 
            if (a == 0 || b == 0)
               return 0;
    
            // base case
            if (a == b)
                return a;
    
            // a is greater
            if (a > b)
                return gcd(a-b, b);
            return gcd(a, b-a);
        }
    
        // Driver method
        public static void main(String[] args) 
        {
            int a = 98, b = 56;
            System.out.println("GCD of " + a +" and " + b + " is " + gcd(a, b));
        }
    }
    
        10
  •  2
  •   MT0    9 年前

    如果使用Java 1.5或更高版本,那么这是一个迭代的二进制GCD算法,它使用 Integer.numberOfTrailingZeros() 减少所需的检查和迭代次数。

    public class Utils {
        public static final int gcd( int a, int b ){
            // Deal with the degenerate case where values are Integer.MIN_VALUE
            // since -Integer.MIN_VALUE = Integer.MAX_VALUE+1
            if ( a == Integer.MIN_VALUE )
            {
                if ( b == Integer.MIN_VALUE )
                    throw new IllegalArgumentException( "gcd() is greater than Integer.MAX_VALUE" );
                return 1 << Integer.numberOfTrailingZeros( Math.abs(b) );
            }
            if ( b == Integer.MIN_VALUE )
                return 1 << Integer.numberOfTrailingZeros( Math.abs(a) );
    
            a = Math.abs(a);
            b = Math.abs(b);
            if ( a == 0 ) return b;
            if ( b == 0 ) return a;
            int factorsOfTwoInA = Integer.numberOfTrailingZeros(a),
                factorsOfTwoInB = Integer.numberOfTrailingZeros(b),
                commonFactorsOfTwo = Math.min(factorsOfTwoInA,factorsOfTwoInB);
            a >>= factorsOfTwoInA;
            b >>= factorsOfTwoInB;
            while(a != b){
                if ( a > b ) {
                    a = (a - b);
                    a >>= Integer.numberOfTrailingZeros( a );
                } else {
                    b = (b - a);
                    b >>= Integer.numberOfTrailingZeros( b );
                }
            }
            return a << commonFactorsOfTwo;
        }
    }
    

    单元测试:

    import java.math.BigInteger;
    import org.junit.Test;
    import static org.junit.Assert.*;
    
    public class UtilsTest {
        @Test
        public void gcdUpToOneThousand(){
            for ( int x = -1000; x <= 1000; ++x )
                for ( int y = -1000; y <= 1000; ++y )
                {
                    int gcd = Utils.gcd(x, y);
                    int expected = BigInteger.valueOf(x).gcd(BigInteger.valueOf(y)).intValue();
                    assertEquals( expected, gcd );
                }
        }
    
        @Test
        public void gcdMinValue(){
            for ( int x = 0; x < Integer.SIZE-1; x++ ){
                int gcd = Utils.gcd(Integer.MIN_VALUE,1<<x);
                int expected = BigInteger.valueOf(Integer.MIN_VALUE).gcd(BigInteger.valueOf(1<<x)).intValue();
                assertEquals( expected, gcd );
            }
        }
    }
    
        11
  •  1
  •   Mohsen Mousavi    6 年前
    public int gcd(int num1, int num2) { 
        int max = Math.abs(num1);
        int min = Math.abs(num2);
    
        while (max > 0) {
            if (max < min) {
                int x = max;
                max = min;
                min = x;
            }
            max %= min;
        }
    
        return min;
    }
    

    该方法利用欧几里得算法求出两个整数的“最大公约数”。它接收两个整数并返回它们的gcd。就这么简单!

        12
  •  0
  •   Gitau Harrison    8 年前
    /*
    import scanner and instantiate scanner class;
    declare your method with two parameters
    declare a third variable;
    set condition;
    swap the parameter values if condition is met;
    set second conditon based on result of first condition;
    divide and assign remainder to the third variable;
    swap the result;
    in the main method, allow for user input;
    Call the method;
    
    */
    public class gcf {
        public static void main (String[]args){//start of main method
            Scanner input = new Scanner (System.in);//allow for user input
            System.out.println("Please enter the first integer: ");//prompt
            int a = input.nextInt();//initial user input
            System.out.println("Please enter a second interger: ");//prompt
            int b = input.nextInt();//second user input
    
    
           Divide(a,b);//call method
        }
       public static void Divide(int a, int b) {//start of your method
    
        int temp;
        // making a greater than b
        if (b > a) {
             temp = a;
             a = b;
             b = temp;
        }
    
        while (b !=0) {
            // gcd of b and a%b
            temp = a%b;
            // always make a greater than b
            a =b;
            b =temp;
    
        }
        System.out.println(a);//print to console
      }
    }
    
        13
  •  0
  •   John Doe    6 年前

    我使用了14岁时创建的方法。

        public static int gcd (int a, int b) {
            int s = 1;
            int ia = Math.abs(a);//<-- turns to absolute value
            int ib = Math.abs(b);
            if (a == b) {
                s = a;
            }else {
                while (ib != ia) {
                    if (ib > ia) {
                        s = ib - ia;
                        ib = s;
                    }else { 
                        s = ia - ib;
                        ia = s;
                    }
                }
            }
            return s;
        }
    
        14
  •  0
  •   Boleslovas Å vitrigaila    6 年前

    它在别的地方吗?

    Apache! -它有GCD和LCM,太酷了!

    但是,由于其实现的深度,与简单的手写版本(如果重要的话)相比,速度较慢。

        15
  •  0
  •   Jin Kwon    6 年前

    GCD功能由 Commons-Math Guava 有一些不同。

    • 公地数学抛出一个 ArithematicException.class 只为 Integer.MIN_VALUE Long.MIN_VALUE .
      • 否则,将值作为绝对值处理。
    • 番石榴抛出一个 IllegalArgumentException.class 对于任何负值。
        16
  •  -3
  •   Mr-Al7lawe    11 年前

    %给我们两个数字之间的GCD,意思是: %或大/小数字的mod=gcd, 我们在Java上这样写 big_number % small_number .

    ex1:对于两个整数

      public static int gcd(int x1,int x2)
        {
            if(x1>x2)
            {
               if(x2!=0)
               {
                   if(x1%x2==0)     
                       return x2;
                       return x1%x2;
                       }
               return x1;
               }
              else if(x1!=0)
              {
                  if(x2%x1==0)
                      return x1;
                      return x2%x1;
                      }
            return x2;
            } 
    

    ex2:三个整数

    public static int gcd(int x1,int x2,int x3)
    {
    
        int m,t;
        if(x1>x2)
            t=x1;
        t=x2;
        if(t>x3)
            m=t;
        m=x3;
        for(int i=m;i>=1;i--)
        {
            if(x1%i==0 && x2%i==0 && x3%i==0)
            {
                return i;
            }
        }
        return 1;
    }