Esiste un metodo che calcola un fattoriale in Java?

Non l’ho trovato, ancora. Ho dimenticato qualcosa? So che un metodo fattoriale è un programma di esempio comune per i principianti. Ma non sarebbe utile avere una implementazione standard per questo da riutilizzare? Potrei usare un tale metodo con tipi standard (int, long …) e anche con BigInteger / BigDecimal.

Non penso sarebbe utile avere una funzione di libreria per factorial. C’è una buona dose di ricerche su implementazioni fattoriali efficienti. Ecco una manciata di implementazioni.

Apache Commons Math ha alcuni metodi fattoriali nella class MathUtils .

public class UsefulMethods { public static long factorial(int number) { long result = 1; for (int factor = 2; factor <= number; factor++) { result *= factor; } return result; } } 

Versione di Big Numbers di 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; } 

I fattoriali nudi nudi sono raramente necessari nella pratica. Molto spesso ti servirà una delle seguenti cose:

1) dividere un fattoriale per un altro, o

2) risposta approssimata a virgola mobile.

In entrambi i casi, starai meglio con semplici soluzioni personalizzate.

Nel caso (1), per esempio, se x = 90! / 85 !, quindi calcolerai il risultato esattamente come x = 86 * 87 * 88 * 89 * 90, senza bisogno di tenere premuto 90! in memoria 🙂

Nel caso (2), google per “Approssimazione di Stirling”.

Usa il BigIntegerMath di Guava come segue:

 BigInteger factorial = BigIntegerMath.factorial(n); 

(Funzionalità simile per int e long è disponibile rispettivamente in IntMath e LongMath .)

Sebbene i fattoriali siano un buon esercizio per i programmatori principianti, nella maggior parte dei casi non sono molto utili e tutti sanno come scrivere una funzione fattoriale, quindi in genere non sono nella libreria media.

credo che questo sarebbe il modo più veloce, da una tabella di ricerca:

 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 20)) throw new OutOfRangeException("n", 0, 20); return FACTORIAL_TABLE[n]; } 

Per il tipo nativo long (8 byte), può contenere solo fino a 20!

 20! = 2432902008176640000(10) = 0x 21C3 677C 82B4 0000 

Ovviamente, 21! causerà overflow.

Pertanto, per tipo nativo long , solo un massimo di 20! è permesso, significativo e corretto.

Poiché factorial cresce così rapidamente, l’overflow dello stack non è un problema se si utilizza la ricorsione. In effetti, il valore di 20! è il più grande può rappresentare in un lungo Java. Quindi il seguente metodo calcola fattoriale (n) o lancia un IllegalArgumentException se n è troppo grande.

 public long factorial(int n) { if (n > 20) throw new IllegalArgumentException(n + " is out of range"); return (1 > n) ? 1 : n * factorial(n - 1); } 

Un altro (più interessante) modo per fare lo stesso è usare la libreria di stream di Java 8 in questo modo:

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

Maggiori informazioni su Factorials utilizzando gli stream di Java 8

Il pacchetto Math Apache Commons ha un metodo fattoriale , penso che potresti usarlo.

La risposta breve è: usare la ricorsione.

È ansible creare un metodo e chiamare tale metodo direttamente all’interno dello stesso metodo in modo ricorsivo:

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

Prova questo

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

Ho trovato un incredibile trucco per trovare fattoriali in metà delle moltiplicazioni effettive.

Per favore sii paziente poichè questo è un post un po ‘lungo.

Per i numeri pari: per dimezzare la moltiplicazione con numeri pari, finirai con n / 2 fattori. Il primo fattore sarà il numero a cui stai prendendo il fattoriale, quindi il prossimo sarà quel numero più quel numero meno due. Il numero successivo sarà il numero precedente più il numero aggiunto aggiunto meno due. Hai finito quando l’ultimo numero che hai aggiunto era due (cioè 2) . Probabilmente non aveva molto senso, quindi lascia che ti dia un esempio.

 8! = 8 * (8 + 6 = 14) * (14 + 4 = 18) * (18 + 2 = 20) 8! = 8 * 14 * 18 * 20 which is **40320** 

Nota che ho iniziato con 8, quindi il primo numero che ho aggiunto era 6, quindi 4, quindi 2, ogni numero aggiunto è due in meno del numero aggiunto prima di esso. Questo metodo equivale a moltiplicare i numeri minimi con i numeri più grandi, solo con una minore moltiplicazione, in questo modo:

 8! = 1 * 2 * 3 * 4 * 5 * 6 * 7 * 8! = (1 * 8) * (2 * 7) * (3 * 6) * (4 * 5) 8! = 8 * 14 * 18 * 20 

Semplice non è 🙂

Now For Odd Numbers: Se il numero è dispari, l’aggiunta è la stessa, poiché in sottrarre due ogni volta, ma ci si ferma alle tre. Il numero di fattori tuttavia cambia. Se dividi il numero per due, finirai con un numero che termina in 0,5. Il motivo è che se moltiplichiamo le estremità insieme, rimaniamo con il numero medio. In sostanza, tutto ciò può essere risolto risolvendo per un numero di fattori uguale al numero diviso per due, arrotondato per eccesso. Questo probabilmente non aveva molto senso né per le menti senza un background matematico, quindi fammi fare un esempio:

 9! = 9 * (9 + 7 = 16) * (16 + 5 = 21) * (21 + 3 = 24) * (roundUp(9/2) = 5) 9! = 9 * 16 * 21 * 24 * 5 = **362880** 

Nota: se non ti piace questo metodo, potresti anche prendere il fattoriale del numero pari prima dello strano (otto in questo caso) e moltiplicarlo per il numero dispari (cioè 9! = 8! * 9).

Ora implementiamo in 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 è una variabile booleana dichiarata come statica; è usato per il primo caso in cui non vogliamo cambiare la sum precedente.

Prova anche con numeri dispari.

Puoi usare la ricorsione.

 public static int factorial(int n){ if (n == 0) return 1; else return(n * factorial(n-1)); } 

e quindi dopo aver creato il metodo (funzione) sopra:

 System.out.println(factorial(number of your choice)); //direct example System.out.println(factorial(3)); 

L’unico uso aziendale per un fattoriale che posso pensare sono le formule Erlang B ed Erlang C, e non tutti lavorano in un call center o per la compagnia telefonica. L’utilità di una funzionalità per le aziende sembra spesso dettare ciò che viene visualizzato in una lingua: esaminare tutte le funzioni di gestione dei dati, XML e Web nelle principali lingue.

È facile mantenere uno snippet fattoriale o una funzione di libreria per qualcosa di simile in giro.

Un metodo molto semplice per calcolare i fattoriali:

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

Ho usato il doppio perché possono contenere numeri enormi, ma puoi usare qualsiasi altro tipo come int, long, float, ecc.

PS Questa potrebbe non essere la soluzione migliore ma sono nuovo nella programmazione e ho impiegato anni per trovare un codice semplice che potesse calcolare i fattoriali, quindi ho dovuto scrivere il metodo da solo, ma lo sto mettendo qui in modo da aiutare le altre persone come me .

Puoi anche usare la versione di ricorsione.

 static int myFactorial(int i) { if(i == 1) return; else System.out.prinln(i * (myFactorial(--i))); } 

La ricorsione è in genere meno efficiente a causa del fatto che è necessario eseguire il push e il pop delle ricorsioni, quindi l’iterazione è più veloce. D’altra parte, le versioni ricorsive usano meno o nessuna variabile locale che è vantaggiosa.

Factorial è una funzionalità discreta altamente crescente. Quindi penso che l’uso di BigInteger sia migliore dell’uso di int. Ho implementato il seguente codice per il calcolo fattoriale di numeri interi non negativi. Ho usato la ricorsione al posto dell’uso di un ciclo.

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

Qui la gamma del grande intero è

 -2^Integer.MAX_VALUE (exclusive) to +2^Integer.MAX_VALUE, where Integer.MAX_VALUE=2^31. 

Tuttavia, l’intervallo del metodo fattoriale sopra riportato può essere esteso fino a due volte utilizzando BigInteger senza segno.

Abbiamo una sola riga per calcolarlo:

 Long factorialNumber = LongStream.rangeClosed(2, N).reduce(1, Math::multiplyExact); 

Un metodo abbastanza semplice

  for ( int i = 1; i < n ; i++ ) { answer = answer * i; } 
  /** 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 
 public static int fact(int i){ if(i==0) return 0; if(i>1){ i = i * fact(--i); } return i; } 

Dobbiamo implementare iterativamente. Se implementiamo in modo ricorsivo, causerà StackOverflow se l’input diventa molto grande (ovvero 2 miliardi). E dobbiamo usare il numero di dimensione non legato come BigInteger per evitare un overflow aritmetico quando un numero fattoriale diventa più grande del numero massimo di un dato tipo (cioè 2 miliardi per int). È ansible utilizzare int per massimo 14 fattoriali e long per massimo 20 fattoriali prima dell’overflow.

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

Se non è ansible utilizzare BigInteger, aggiungere un controllo degli errori.

 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; } 
 public int factorial(int num) { if (num == 1) return 1; return num * factorial(num - 1); } 

ciclo while (per piccoli numeri)

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

Ho preso questo da EDX usarlo! è chiamato ricorsione

  public static int factorial(int n) { if (n == 1) { return 1; } else { return n * factorial(n-1); } } 

con ricorsione:

 public static int factorial(int n) { if(n == 1) { return 1; } return n * factorial(n-1); } 

con ciclo while:

 public static int factorial1(int n) { int fact=1; while(n>=1) { fact=fact*n; n--; } return fact; }