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?
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;
}
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)
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 )
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
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.
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);
}
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);
}
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.
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.
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());