web-dev-qa-db-fra.com

Comment trouver GCD, LCM sur un ensemble de nombres

Quel serait le moyen le plus facile de calculer le plus grand commun diviseur et le plus petit commun multiple sur un ensemble de nombres? Quelles fonctions mathématiques peuvent être utilisées pour trouver cette information?

62
user339108

J'ai utilisé algorithme d'Euclid pour trouver le plus grand commun diviseur de deux nombres; il peut être itéré d’obtenir le GCD d’un plus grand ensemble de nombres.

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

Le plus petit commun multiple est un peu plus compliqué, mais la meilleure approche est probablement réduction par le GCD , qui peut être itérée de la même façon:

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

Il y a un algorithme d'Euclid pour GCD,

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

À propos, a et b devraient être supérieurs ou égaux à 0, Et LCM = |ab| / GCF(a, b)

23
RyuuGan

Il n'y a pas de fonction de construction pour cela. Vous pouvez trouver le GCD de deux nombres en utilisant algorithme d'Euclid .

Pour un ensemble de nombre

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

Appliquez-le récursivement.

Idem pour 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

Si vous pouvez utiliser Java 8 (et le souhaitez réellement)), vous pouvez utiliser des expressions lambda pour résoudre ce problème de manière fonctionnelle:

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

Je me suis orienté sur réponse de Jeffrey Hantin , mais

  • calculé fonctionnellement le gcd
  • utilisé la syntaxe varargs pour une API plus simple (je n'étais pas sûr que la surcharge fonctionnerait correctement, mais cela fonctionne sur ma machine)
  • transformé le gcd du numbers- Array en syntaxe fonctionnelle, plus compacte et plus facile à lire (au moins si vous êtes habitué à la programmation fonctionnelle)

Cette approche est probablement légèrement plus lente en raison d'appels de fonction supplémentaires, mais cela n'aura probablement aucune importance pour la plupart des cas d'utilisation.

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

Avec Java 8, il existe des moyens plus élégants et fonctionnels de résoudre ce problème.

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

Bien sûr, si un argument est 0, les deux méthodes ne fonctionneront pas.

1
AdHominem

Fondamentalement, pour trouver gcd et lcm sur un ensemble de nombres, vous pouvez utiliser la formule ci-dessous,

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

En attendant, dans Java, vous pouvez utiliser l'algorithme d'euclid pour trouver gcd et lcm, comme ceci

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

Vous pouvez vous référer à this ressource pour trouver des exemples d'algorithme euclid.

0
Shiva

pour gcd vous pouvez faire comme ci-dessous:

    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