Java:获取最大公约数

Java:获取最大公约数,java,greatest-common-divisor,Java,Greatest Common Divisor,我已经看到,biginger存在这样一个函数,即。Java中是否有其他函数也适用于其他类型(int、long或Integer)?看起来这对于java.lang.Math.gcd(使用各种重载)来说是有意义的,但它并不存在。是在别的地方吗 (请不要把这个问题和“我自己如何实现它”混为一谈!)对于int和long,作为原语,不是真的。对于Integer,可能有人编写了一个 假设BigInteger是int、Integer、long和long的(数学/函数)超集,如果需要使用这些类型,请将它们转换为

我已经看到,
biginger
存在这样一个函数,即。Java中是否有其他函数也适用于其他类型(
int
long
Integer
)?看起来这对于
java.lang.Math.gcd
(使用各种重载)来说是有意义的,但它并不存在。是在别的地方吗



(请不要把这个问题和“我自己如何实现它”混为一谈!)

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

假设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();
}

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

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); }

应该注意的是,这两种方法编译成相同的字节码,因此它们之间绝对没有区别。

或者用于计算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;
}

雅加达公共数学正是如此


将给我们两个数字之间的gcd,它意味着:- %或大号/小号的mod=gcd, 我们在java上这样编写
big\u number%small\u 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;
}

您可以使用

公共类二进制gcd{
公共静态int gcd(int p,int q){
如果(q==0)返回p;
如果(p==0)返回q;
//p和q偶数
如果((p&1)==0&(q&1)==0)返回gcd(p>>1,q>>1)>1,q);
//p是奇数,q是偶数
否则如果((q&1)==0)返回gcd(p,q>>1);
//p和q奇数,p>=q
否则,如果(p>=q)返回gcd((p-q)>>1,q);
//p和q奇数,p>1);
}
公共静态void main(字符串[]args){
int p=Integer.parseInt(args[0]);
intq=Integer.parseInt(args[1]);
System.out.println(“gcd(“+p+”,“+q+””)=“+gcd(p,q));
}
}


开始,使用番石榴和

如果两个数字都为负数,则此处的一些实现无法正常工作。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);
}

如果您使用的是Java1.5或更高版本,那么这是一种迭代二进制GCD算法,用于减少所需的检查和迭代次数

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;
    }
}
公共类Utils{
公共静态最终整数gcd(整数a、整数b){
//处理值为Integer.MIN_值的退化情况
//因为-Integer.MIN\u值=Integer.MAX\u值+1
if(a==Integer.MIN_值)
{
if(b==Integer.MIN_值)
抛出新的IllegalArgumentException(“gcd()大于Integer.MAX_值”);
return 1=factorsOfTwoInA;
b>>=系数oftwoinb;
while(a!=b){
如果(a>b){
a=(a-b);
a>>=整数。跟踪零的数目(a);
}否则{
b=(b-a);
b>>=整数。跟踪零的数目(b);
}
}

返回a除非我有番石榴,否则我定义如下:

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

我们可以使用递归函数来查找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));
    }
}

我使用了我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;
    }
publicstaticintgcd(inta,intb){
int s=1;
int ia=Math.abs(a);//ia){
s=ib-ia;
ib=s;
}否则{
s=ia-ib;
ia=s;
}
}
}
返回s;
}
public int-gcd(int-num1,int-num2){
int max=数学绝对值(num1);
int min=数学绝对值(num2);
而(最大值>0){
如果(最大值<最小值){
int x=最大值;
最大值=最小值;
min=x;
}
最大%=最小值;
}
返回最小值;
}
这个方法使用欧几里德算法来获得两个整数的“最大公约数”。它接收两个整数并返回它们的gcd。就这么简单

是在别的地方吗

-它有gcd和lcm,太酷了


然而,由于其实现的深度,它比简单的手写版本(如果有必要的话)要慢。

由和提供的GCD函数有些不同

  • Commons Math仅为
    整数.MIN\u值
    长.MIN\u值
    抛出一个。
    • 否则,将该值作为绝对值处理
  • 番石榴对任何负值抛出一个
    IllegalArgumentException.class

据我所知,它运行得很好。我只运行了100000个随机数,虽然这两种方法每次都是一致的。这是欧几里德算法……它非常古老,并且被证明是正确的。是的,我可以看到它,但我需要更多的时间来完成它。我喜欢它。@Albert,你可以用泛型类型来尝试它,看看它是否有效。我不知道o只是一个想法,但算法是供您试验的。对于一些标准库或类,我从未见过。您仍然需要在创建对象时指定它是int、long等。尽管如此。@Albert,虽然Matt提供了一个实现,但您自己可以让它在,“更通用”的方式,不是吗?:)只是澄清一下:这绝对不是我想要的。在这种情况下,你没有指定你不想要替代的实现,因为一个不存在。只是后来你编辑了你的帖子,没有寻找实现。我相信其他人已经回答“不”“非常充分。如果a非常大而b很小,则速度会很慢。%”解决方案会快得多。
biginger.valueOf(a).gcd(biginger.valueOf(b)).intValue()
。一些基准测试:如果经常调用此函数(即。
int gcd(int a, int b) {
  return a == 0 ? b : gcd(b % a, a);
}
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));
    }
}
    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;
    }
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;
}