web-dev-qa-db-ja.com

一連の数値でGCD、LCMを見つける方法

一連の数値で最大公約数と最小公倍数を計算する最も簡単な方法は何ですか?この情報を見つけるためにどの数学関数を使用できますか?

62
user339108

Euclidのアルゴリズム を使用して、2つの数値の最大公約数を見つけました。より大きな数のセットのGCDを取得するために反復できます。

private static long gcd(long a, long b)
{
    while (b > 0)
    {
        long temp = b;
        b = a % b; // % is remainder
        a = temp;
    }
    return a;
}

private static long gcd(long[] input)
{
    long result = input[0];
    for(int i = 1; i < input.length; i++) result = gcd(result, input[i]);
    return result;
}

最小公倍数は少し複雑ですが、おそらく最良のアプローチは GCDによる削減 であり、同様に反復できます:

private static long lcm(long a, long b)
{
    return a * (b / gcd(a, b));
}

private static long gcd(long[] input)
{
    long result = input[0];
    for(int i = 1; i < input.length; i++) result = lcm(result, input[i]);
    return result;
}
133
Jeffrey Hantin

GCDには Euclidのアルゴリズム があり、

_public int GCF(int a, int b) {
    if (b == 0) return a;
    else return (GCF (b, a % b));
}
_

ちなみに、abは_0_以上である必要があり、 [〜#〜] lcm [〜#〜] = |ab| / GCF(a, b)

23
RyuuGan

組み込みの機能はありません。 Euclidのアルゴリズム を使用して、2つの数値のGCDを見つけることができます。

数字のセットについて

GCD(a_1,a_2,a_3,...,a_n) = GCD( GCD(a_1, a_2), a_3, a_4,..., a_n )

再帰的に適用します。

LCMについても同じ:

LCM(a,b) = a * b / GCD(a,b)
LCM(a_1,a_2,a_3,...,a_n) = LCM( LCM(a_1, a_2), a_3, a_4,..., a_n )
13
J-16 SDiZ

Java 8(実際に使いたい))を使用できる場合、ラムダ式を使用してこれを機能的に解決できます。

private static int gcd(int x, int y) {
    return (y == 0) ? x : gcd(y, x % y);
}

public static int gcd(int... numbers) {
    return Arrays.stream(numbers).reduce(0, (x, y) -> gcd(x, y));
}

public static int lcm(int... numbers) {
    return Arrays.stream(numbers).reduce(1, (x, y) -> x * (y / gcd(x, y)));
}

Jeffrey Hantin's answer に焦点を当てましたが、

  • gcdを機能的に計算しました
  • より簡単なAPIにvarargs-Syntaxを使用しました(オーバーロードが正しく機能するかどうかはわかりませんでしたが、私のマシンでは機能します)
  • numbers- Arrayのgcdを関数型構文に変換しました。これは、よりコンパクトで読みやすいIMOです(少なくとも関数型プログラミングに慣れている場合)

このアプローチは、追加の関数呼び出しのためにおそらくわずかに遅くなりますが、ほとんどのユースケースではおそらくまったく問題になりません。

6
Qw3ry
int gcf(int a, int b)
{
    while (a != b) // while the two numbers are not equal...
    { 
        // ...subtract the smaller one from the larger one

        if (a > b) a -= b; // if a is larger than b, subtract b from a
        else b -= a; // if b is larger than a, subtract a from b
    }

    return a; // or return b, a will be equal to b either way
}

int lcm(int a, int b)
{
    // the lcm is simply (a * b) divided by the gcf of the two

    return (a * b) / gcf(a, b);
}
4
user3026735
int lcmcal(int i,int y)
{
    int n,x,s=1,t=1;
    for(n=1;;n++)
    {
        s=i*n;
        for(x=1;t<s;x++)
        {
            t=y*x;
        }
        if(s==t)
            break;
    }
    return(s);
}
2
saif

Java 8では、これを解決するよりエレガントで機能的な方法があります。

LCM:

private static int lcm(int numberOne, int numberTwo) {
    final int bigger = Math.max(numberOne, numberTwo);
    final int smaller = Math.min(numberOne, numberTwo);

    return IntStream.rangeClosed(1,smaller)
                    .filter(factor -> (factor * bigger) % smaller == 0)
                    .map(factor -> Math.abs(factor * bigger))
                    .findFirst()
                    .getAsInt();
}

GCD:

private static int gcd(int numberOne, int numberTwo) {
    return (numberTwo == 0) ? numberOne : gcd(numberTwo, numberOne % numberTwo);
}

もちろん、1つの引数が0の場合、両方のメソッドは機能しません。

1
AdHominem

基本的に、次の式で使用できる一連の数値でgcdとlcmを見つけるには、

LCM(a, b) X HCF(a, b) = a * b

一方、Javaでは、euclidのアルゴリズムを使用して、次のようにgcdとlcmを見つけることができます。

public static int GCF(int a, int b)
{
    if (b == 0)
    {
       return a;
    }
    else
    {
       return (GCF(b, a % b));
    }
}

this リソースを参照して、euclidのアルゴリズムの例を見つけることができます。

0
Shiva

gcdの場合、次のようにcadを実行します。

    String[] ss = new Scanner(System.in).nextLine().split("\\s+");
    BigInteger bi,bi2 = null;
    bi2 = new BigInteger(ss[1]);
    for(int i = 0 ; i<ss.length-1 ; i+=2 )
    {
        bi = new BigInteger(ss[i]);
        bi2 = bi.gcd(bi2);
    }
    System.out.println(bi2.toString());
0
parsa