programing

Java: 최대 공약수 가져오기

goodjava 2023. 1. 24. 08:10

Java: 최대 공약수 가져오기

을 본 .BigInteger(예: 다른 타입에서도 동작하는 다른 기능이 자바에 있습니까?)int,long ★★★★★★★★★★★★★★★★★」Integer( )? 이것은 이치에 맞는 것 같습니다.java.lang.Math.gcd(모든 종류의 과부하로) 하지만 거기엔 없어요.른른른른른른른른?


(이 질문을 "내가 직접 구현하는 방법"과 혼동하지 마십시오.)

제가 아는 한, 원형을 위한 기본 제공 방법은 없습니다.하지만 다음과 같은 간단한 것이 효과가 있습니다.

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

같은 바이트 코드로 컴파일하기 때문에 이 둘은 전혀 차이가 없다는 점에 유의해야 합니다.

아주 오랫동안, 원초적인 것으로서, 사실은 그렇지 않다.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();
}

아니면 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;
}

Guava가 없는 한 다음과 같이 정의합니다.

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

Guava와

자카르타 커먼즈 수학은 바로 그 점을 가지고 있다.

산술유틸스.gcd(int p, int q)

이 바이너리 GCD 알고리즘의 실장을 사용할 수 있습니다.

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 에서

양쪽 수치가 음수인 경우는, 일부의 실장이 올바르게 동작하고 있지 않습니다.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);
}

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

이 방법은 유클리드의 알고리즘을 사용하여 두 정수의 "가장 큰 공약수"를 구합니다.2개의 정수를 수신하여 그 gcd를 반환합니다.그렇게 간단해!

Java 1.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;
    }
}

유닛 테스트:

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

다른 데 있어요?

Apache! - gcd와 lcm 둘 다 있어 멋지다!

그러나 구현의 심오함 때문에 간단한 수기 버전에 비해 속도가 느립니다(중요한 경우).

/*
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
  }
}

저는 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;
    }

Commons-MathGuava가 제공하는 GCD 함수는 몇 가지 차이가 있다.

  • Commons-Math는 에 대해서만 우열을 가린다.Integer.MIN_VALUE또는Long.MIN_VALUE.
    • 그렇지 않으면 절대값으로 처리됩니다.
  • 구아바가 던지다IllegalArgumentException.class음의 값을 지정합니다.

gcd를 주는 %는 두 숫자 사이의 - % 또는 big_number/small_number의 mod는 =gcd이고, 우리는 그것을 다음과 같이 자바에 씁니다.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: 3개의 정수

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

언급URL : https://stackoverflow.com/questions/4009198/java-get-greatest-common-divisor