Je ne l'ai pas encore trouvé. Ai-je manqué quelque chose? Je sais qu'une méthode factorielle est un exemple de programme courant pour les débutants. Mais ne serait-il pas utile d’avoir une implémentation standard que celle-ci puisse réutiliser?.
Je ne pense pas qu'il serait utile d'avoir une fonction de bibliothèque pour factorielle. Il y a beaucoup de recherches sur des implémentations factorielles efficaces. Voici une poignée d'implémentations.
Apache Commons Math a quelques méthodes factorielles dans la classe MathUtils .
public class UsefulMethods {
public static long factorial(int number) {
long result = 1;
for (int factor = 2; factor <= number; factor++) {
result *= factor;
}
return result;
}
}
Version Big Numbers par HoldOffHunger :
public static BigInteger factorial(BigInteger number) {
BigInteger result = BigInteger.valueOf(1);
for (long factor = 2; factor <= number.longValue(); factor++) {
result = result.multiply(BigInteger.valueOf(factor));
}
return result;
}
Les factorielles nues nues sont rarement nécessaires dans la pratique. Le plus souvent, vous aurez besoin de l'un des éléments suivants:
1) diviser une factorielle par une autre, ou
2) réponse en virgule flottante approximée.
Dans les deux cas, vous seriez mieux avec des solutions personnalisées simples.
Dans le cas (1), disons, si x = 90!/85 !, alors vous calculerez le résultat de la manière suivante: x = 86 * 87 * 88 * 89 * 90, sans qu'il soit nécessaire de conserver 90! en mémoire :)
Dans le cas (2), recherchez Google "approximation de Stirling".
Utilisez BigIntegerMath
comme suit:
BigInteger factorial = BigIntegerMath.factorial(n);
(Une fonctionnalité similaire pour int
et long
est disponible dans IntMath
et LongMath
.)
je crois que ce serait le moyen le plus rapide, par une table de recherche:
private static final long[] FACTORIAL_TABLE = initFactorialTable();
private static long[] initFactorialTable() {
final long[] factorialTable = new long[21];
factorialTable[0] = 1;
for (int i=1; i<factorialTable.length; i++)
factorialTable[i] = factorialTable[i-1] * i;
return factorialTable;
}
/**
* Actually, even for {@code long}, it works only until 20 inclusively.
*/
public static long factorial(final int n) {
if ((n < 0) || (n > 20))
throw new OutOfRangeException("n", 0, 20);
return FACTORIAL_TABLE[n];
}
Pour le type natif long
(8 octets), il ne peut contenir que 20!
20! = 2432902008176640000(10) = 0x 21C3 677C 82B4 0000
De toute évidence, 21!
provoquera un débordement.
Par conséquent, pour le type natif long
, seul un maximum de 20!
est autorisé, significatif et correct.
En raison de la croissance rapide de la factorielle, le dépassement de pile n'est pas un problème si vous utilisez la récursivité. En fait, la valeur de 20! est le plus grand que l’on puisse représenter dans une longue Java. La méthode suivante calcule alors factorielle (n) ou lève une exception IllegalArgumentException si n est trop grand.
public long factorial(int n) {
if (n > 20) throw new IllegalArgumentException(n + " is out of range");
return (1 > n) ? 1 : n * factorial(n - 1);
}
Une autre façon (plus cool) de faire la même chose consiste à utiliser la bibliothèque de flux de Java 8 comme ceci:
public long factorial(int n) {
if (n > 20) throw new IllegalArgumentException(n + " is out of range");
return LongStream.rangeClosed(1, n).reduce(1, (a, b) -> a * b);
}
Lire plus sur Factorials utilisant les flux de Java 8
Apache Commons Math contient une méthode factorielle , je pense que vous pourriez l'utiliser.
La réponse courte est: utilisez la récursivité.
Vous pouvez créer une méthode et appeler cette méthode directement dans la même méthode de manière récursive:
public class factorial {
public static void main(String[] args) {
System.out.println(calc(10));
}
public static long calc(long n) {
if (n <= 1)
return 1;
else
return n * calc(n - 1);
}
}
Bien que les factorielles fassent un bel exercice pour le programmeur débutant, elles ne sont pas très utiles dans la plupart des cas, et tout le monde sait comment écrire une fonction factorielle; elles ne font donc généralement pas partie de la bibliothèque moyenne.
Essaye ça
public static BigInteger factorial(int value){
if(value < 0){
throw new IllegalArgumentException("Value must be positive");
}
BigInteger result = BigInteger.ONE;
for (int i = 2; i <= value; i++) {
result = result.multiply(BigInteger.valueOf(i));
}
return result;
}
J'ai trouvé un truc incroyable pour trouver des factorielles dans seulement la moitié des multiplications réelles.
S'il vous plaît soyez patient car c'est un peu d'un long post.
Pour les nombres pairs: Pour réduire de moitié la multiplication avec des nombres pairs, vous obtiendrez n/2 facteurs. Le premier facteur sera le nombre dont vous prenez la factorielle, puis le suivant sera ce nombre plus ce nombre moins deux. Le prochain numéro sera le numéro précédent plus le dernier numéro ajouté moins deux. Vous avez terminé lorsque le dernier numéro ajouté était deux (c'est-à-dire 2) . Cela n’a probablement pas beaucoup de sens, alors laissez-moi vous donner un exemple.
8! = 8 * (8 + 6 = 14) * (14 + 4 = 18) * (18 + 2 = 20)
8! = 8 * 14 * 18 * 20 which is **40320**
Notez que j'ai commencé avec 8, puis le premier nombre que j'ai ajouté était 6, puis 4, puis 2, chaque nombre ajouté étant inférieur de deux au nombre ajouté avant lui. Cette méthode équivaut à multiplier le plus petit nombre par le plus grand nombre, juste avec la moindre multiplication, comme ceci:
8! = 1 * 2 * 3 * 4 * 5 * 6 * 7 *
8! = (1 * 8) * (2 * 7) * (3 * 6) * (4 * 5)
8! = 8 * 14 * 18 * 20
Simple n'est-ce pas :)
Maintenant pour les nombres impairs: Si le nombre est impair, l'addition est la même, puisque vous en soustrayez deux à chaque fois, mais que vous vous arrêtez à trois. Le nombre de facteurs change cependant. Si vous divisez le nombre par deux, vous vous retrouverez avec un nombre se terminant par 0,5. La raison en est que si nous multiplions les extrémités, nous nous retrouvons avec le nombre du milieu. Fondamentalement, tout cela peut être résolu en résolvant un nombre de facteurs égal au nombre divisé par deux, arrondi. Cela n’a probablement pas beaucoup de sens non plus pour les esprits sans formation mathématique, alors laissez-moi vous donner un exemple:
9! = 9 * (9 + 7 = 16) * (16 + 5 = 21) * (21 + 3 = 24) * (roundUp(9/2) = 5)
9! = 9 * 16 * 21 * 24 * 5 = **362880**
Remarque: Si vous n'aimez pas cette méthode, vous pouvez également prendre la factorielle du nombre pair avant l'inverse (huit dans ce cas) et la multiplier par le nombre impair (c'est-à-dire 9! = 8! * 9).
Maintenant, implémentons-le en Java:
public static int getFactorial(int num)
{
int factorial=1;
int diffrennceFromActualNum=0;
int previousSum=num;
if(num==0) //Returning 1 as factorial if number is 0
return 1;
if(num%2==0)// Checking if Number is odd or even
{
while(num-diffrennceFromActualNum>=2)
{
if(!isFirst)
{
previousSum=previousSum+(num-diffrennceFromActualNum);
}
isFirst=false;
factorial*=previousSum;
diffrennceFromActualNum+=2;
}
}
else // In Odd Case (Number * getFactorial(Number-1))
{
factorial=num*getFactorial(num-1);
}
return factorial;
}
isFirst
est une variable booléenne déclarée comme statique; il est utilisé pour le 1er cas où nous ne souhaitons pas modifier la somme précédente.
Essayez avec même que pour les nombres impairs.
Vous pouvez utiliser la récursivité.
public static int factorial(int n){
if (n == 0)
return 1;
else
return(n * factorial(n-1));
}
et après avoir créé la méthode (fonction) ci-dessus:
System.out.println(factorial(number of your choice));
//direct example
System.out.println(factorial(3));
Une méthode assez simple
for ( int i = 1; i < n ; i++ )
{
answer = answer * i;
}
Une méthode très simple pour calculer les factorielles:
private double FACT(double n) {
double num = n;
double total = 1;
if(num != 0 | num != 1){
total = num;
}else if(num == 1 | num == 0){
total = 1;
}
double num2;
while(num > 1){
num2 = num - 1;
total = total * num2;
num = num - 1;
}
return total;
}
J'ai utilisé double parce qu'ils peuvent contenir des nombres énormes, mais vous pouvez utiliser n'importe quel autre type comme int, long, float, etc.
P.S. Ce n'est peut-être pas la meilleure solution, mais je suis novice en codage et il m'a fallu un bon bout de temps pour trouver un code simple permettant de calculer des factorielles;.
Factorielle est une fonction discrète de plus en plus croissante. Je pense donc que l’utilisation de BigInteger est préférable à celle de int .J'ai mis en œuvre le code suivant pour le calcul de la factorielle des entiers non négatifs.J'ai utilisé la récursion au lieu de l’utilisation d’une boucle.
public BigInteger factorial(BigInteger x){
if(x.compareTo(new BigInteger("1"))==0||x.compareTo(new BigInteger("0"))==0)
return new BigInteger("1");
else return x.multiply(factorial(x.subtract(new BigInteger("1"))));
}
Ici la gamme de grand entier est
-2^Integer.MAX_VALUE (exclusive) to +2^Integer.MAX_VALUE,
where Integer.MAX_VALUE=2^31.
Cependant, la plage de la méthode factorielle donnée ci-dessus peut être étendue jusqu'à deux fois en utilisant BigInteger non signé.
Vous pouvez également utiliser la version récursive.
static int myFactorial(int i) {
if(i == 1)
return;
else
System.out.prinln(i * (myFactorial(--i)));
}
La récursivité est généralement moins efficace en raison de la nécessité de recourir à des récursions Push et Pop. L'itération est donc plus rapide. D'autre part, les versions récursives utilisent peu ou pas de variables locales, ce qui est un avantage.
Les formules Erlang B et Erlang C sont les seules utilisations possibles d’une factorielle auxquelles je puisse penser, et tout le monde ne travaille pas dans un centre d’appel ou pour une compagnie de téléphone. L'utilité d'une fonctionnalité pour les entreprises semble souvent dicter ce qui apparaît dans une langue: examinez toutes les fonctions de traitement des données, XML et Web dans les principales langues.
Il est facile de conserver un extrait factoriel ou une fonction de bibliothèque pour quelque chose comme ceci.
/**
import Java liberary class
*/
import Java.util.Scanner;
/* class to find factorial of a number
*/
public class factorial
{
public static void main(String[] args)
{
// scanner method for read keayboard values
Scanner factor= new Scanner(System.in);
int n;
double total = 1;
double sum= 1;
System.out.println("\nPlease enter an integer: ");
n = factor.nextInt();
// evaluvate the integer is greater than zero and calculate factorial
if(n==0)
{
System.out.println(" Factorial of 0 is 1");
}
else if (n>0)
{
System.out.println("\nThe factorial of " + n + " is " );
System.out.print(n);
for(int i=1;i<n;i++)
{
do // do while loop for display each integer in the factorial
{
System.out.print("*"+(n-i) );
}
while ( n == 1);
total = total * i;
}
// calculate factorial
sum= total * n;
// display sum of factorial
System.out.println("\n\nThe "+ n +" Factorial is : "+" "+ sum);
}
// display invalid entry, if enter a value less than zero
else
{
System.out.println("\nInvalid entry!!");
}System.exit(0);
}
}
Nous avons une seule ligne pour le calculer:
Long factorialNumber = LongStream.rangeClosed(2, N).reduce(1, Math::multiplyExact);
boucle while (pour les petits nombres)
public class factorial {
public static void main(String[] args) {
int counter=1, sum=1;
while (counter<=10) {
sum=sum*counter;
counter++;
}
System.out.println("Factorial of 10 is " +sum);
}
}
Juste pour le fun: Une méthode factorielle à une ligne qui fonctionne avec BigInteger
:
private static BigInteger calculateFactorial(BigInteger value)
{
return value.subtract(BigInteger.ONE).compareTo(BigInteger.ONE) == 0 ? value : value.multiply(calculateFactorial(value.subtract(BigInteger.ONE)));
}
public int factorial(int num) {
if (num == 1) return 1;
return num * factorial(num - 1);
}
public static int fact(int i){
if(i==0)
return 0;
if(i>1){
i = i * fact(--i);
}
return i;
}
TILISATION DE LA PROGRAMMATION DYNAMIQUE IS EFFICIENT
si vous voulez l'utiliser pour calculer encore et encore (comme la mise en cache)
Code Java:
int fact[]=new int[n+1]; //n is the required number you want to find factorial for.
int factorial(int num)
{
if(num==0){
fact[num]=1;
return fact[num];
}
else
fact[num]=(num)*factorial(num-1);
return fact[num];
}
Nous devons mettre en œuvre de manière itérative. Si nous implémentons de manière récursive, cela provoquera StackOverflow si l’entrée devient très grosse (c’est-à-dire 2 milliards). Et nous devons utiliser un numéro de taille non lié tel que BigInteger pour éviter un débordement arithmatique lorsqu'un nombre factoriel devient supérieur au nombre maximal d'un type donné (c'est-à-dire 2 milliards pour l'int. Vous pouvez utiliser int pour maximum 14 de factorielle et long pour maximum 20 De factoriel avant le débordement.
public BigInteger getFactorialIteratively(BigInteger input) {
if (input.compareTo(BigInteger.ZERO) <= 0) {
throw new IllegalArgumentException("zero or negatives are not allowed");
}
BigInteger result = BigInteger.ONE;
for (BigInteger i = BigInteger.ONE; i.compareTo(input) <= 0; i = i.add(BigInteger.ONE)) {
result = result.multiply(i);
}
return result;
}
Si vous ne pouvez pas utiliser BigInteger, ajoutez une vérification d'erreur.
public long getFactorialIteratively(long input) {
if (input <= 0) {
throw new IllegalArgumentException("zero or negatives are not allowed");
} else if (input == 1) {
return 1;
}
long prev = 1;
long result = 0;
for (long i = 2; i <= input; i++) {
result = prev * i;
if (result / prev != i) { // check if result holds the definition of factorial
// arithmatic overflow, error out
throw new RuntimeException("value "+i+" is too big to calculate a factorial, prev:"+prev+", current:"+result);
}
prev = result;
}
return result;
}
Je l'ai eu d'EDX, utilisez-le! sa récursion appelée
public static int factorial(int n) {
if (n == 1) {
return 1;
} else {
return n * factorial(n-1);
}
}
avec récursion:
public static int factorial(int n)
{
if(n == 1)
{
return 1;
}
return n * factorial(n-1);
}
avec boucle while:
public static int factorial1(int n)
{
int fact=1;
while(n>=1)
{
fact=fact*n;
n--;
}
return fact;
}