CodeGym /Java Blog /Random-IT /Programma Java per fattoriale
John Squirrels
Livello 41
San Francisco

Programma Java per fattoriale

Pubblicato nel gruppo Random-IT
Oggi parleremo dei fattoriali e dei modi più comuni per trovare il fattoriale. Questa è una delle funzioni più basilari che un programmatore deve conoscere ed essere in grado di lavorare. Bene, cominciamo. Il fattoriale del numero n, indicato come n!, è il valore del prodotto (moltiplicazione) di tutti i numeri naturali da 1 a n. Ecco come appare (aggiorniamo la tua conoscenza della matematica):
1! = 1 2! = 1 * 2 = 2 3! = 1 * 2 * 3 = 6 4! = 1 * 2 * 3 * 4 = 24 5! = 1 * 2 * 3 * 4 * 5 = 120
E c'è un'altra piccola regola per 0:
!0 = 1
Se vogliamo calcolare la differenza tra 6! e 4!:
6!-4! = 1⋅2⋅3⋅4⋅5⋅6 - 1⋅2⋅3⋅4 = 720 - 24 = 696
Vediamo come sarebbe una volta implementato nella programmazione. Esploreremo alcuni modi per eseguire calcoli di fattoriale in Java.

Soluzione ordinaria in programma fattoriale

Ecco un semplice programma fattoriale che utilizza il ciclo:

class FactorialExample{  
 public static void main(String args[]){  
  int i,fact=1;  
  int number=7;// our number to do the necessary calculations in class Factorial    
  for(i=1;i<=number;i++){    
      fact=fact*i;    
  }    
  System.out.println("Factorial of "+number+" is: "+fact);    
 }  
}
Il nostro output su console sarà:
Il fattoriale di 7 è: 5040
E un altro esempio per sistemare le cose:

public static int getFactorial(int f) {
  int result = 1;
  for (int i = 1; i <= f; i++) {
     result = result * i; // finding factorial of number using loops
  }
  return result;
}
Niente di difficile qui: usiamo il numero passato come dimensione del nostro ciclo, in cui moltiplichiamo per tutti i numeri precedenti fino ad arrivare a f. E principalmente:

System.out.println(getFactorial(6) - getFactorial(4));
Testando il codice, vediamo che otteniamo il risultato desiderato: 696.

Soluzione ricorsiva

La ricorsione si verifica quando un metodo chiama se stesso. Tale metodo è chiamato metodo ricorsivo. Di norma, si compone di due parti:
  1. Una condizione di terminazione: quando la condizione di terminazione è soddisfatta, il metodo dovrebbe smettere di chiamare se stesso e iniziare a passare i valori. Dopo tutto, se non c'è una condizione di terminazione, allora avremo un ciclo infinito, con il metodo che si chiama ripetutamente finché non otteniamo un StackOverflowError .
  2. Qualunque sia la logica richiesta dalla situazione più una chiamata ricorsiva, ma con un valore di input diverso.
Trovare il fattoriale in Java è un perfetto esempio di quando usare la ricorsione:

public static int getFactorial(int f) { // finding factorial of number using recursive solution
  if (f <= 1) {
     return 1;
  }
  else {
     return f * getFactorial(f - 1);
  }
}
La nostra condizione di terminazione della ricorsione sarà quando raggiungiamo 1. Se il parametro non è 1, moltiplichiamo il valore corrente per il risultato della successiva chiamata ricorsiva al metodo (a cui passiamo il valore corrente meno 1).

Soluzione con un flusso

Chiunque non abbia familiarità con la funzionalità Stream di Java, o chiunque voglia rinfrescare la memoria, trarrà beneficio dalla lettura qui .

public static int getFactorial(int f) { // finding factorial of number using Stream 
  if (f <= 1) {
     return 1;
  }
  else {
     return IntStream.rangeClosed(2, f).reduce((x, y) -> x * y).getAsInt();
  }
}
Qui usiamo la speciale classe IntStream , che ci offre capacità aggiuntive quando lavoriamo con un flusso di valori int. Per creare un flusso di questo tipo, utilizziamo il suo metodo statico rangeClosed , che genera valori da 2 a f, inclusi, in incrementi di 1. Successivamente, utilizziamo il metodo reduce per combinare tutti i valori. Più specificamente, mostriamo come vogliamo combinare i valori. Infine, otteniamo il valore risultante utilizzando il metodo getAsInt del terminale .

Utilizzo di BigInteger

In Java, la classe BigInteger viene spesso utilizzata per gestire i numeri, in particolare i numeri BIG. In effetti, se usiamo int , il fattoriale massimo che possiamo gestire senza perdita di dati è 31. Per il tipo di dati lungo , il fattoriale massimo è 39. Ma cosa succede se abbiamo bisogno del fattoriale di 100? Adattiamo le soluzioni precedenti a BigInteger.Programma java per fattoriale - 2

Soluzione ordinaria


public static BigInteger getFactorial(int f) { // finding factorial of number using BigInteger
  BigInteger result = BigInteger.ONE;
  for (int i = 1; i <= f; i++)
     result = result.multiply(BigInteger.valueOf(i));
  return result;
}
L'algoritmo è essenzialmente lo stesso, ma qui utilizziamo le funzionalità di BigInteger: BigInteger.ONE è il valore iniziale 1 e multiply() viene utilizzato per moltiplicare il valore fattoriale precedente e il numero corrente.

Soluzione ricorsiva


public static BigInteger getFactorial(int f) {
  if (f <= 1) {
     return BigInteger.valueOf(1);
  }
  else {
     return BigInteger.valueOf(f).multiply(getFactorial(f - 1));
  }
}
La logica generale della soluzione non cambia, tranne per il fatto che vengono aggiunti alcuni metodi per lavorare con BigInteger.

Soluzione con un flusso


public static BigInteger getFactorial(int f) {
  if (f < 2) {
     return BigInteger.valueOf(1);
  }
  else {
     return IntStream.rangeClosed(2, f).mapToObj(BigInteger::valueOf).reduce(BigInteger::multiply).get();
  }
}
Tutto è essenzialmente uguale, ma con BigInteger. La classe Stream ci fornisce il metodo mapToObj , che utilizziamo per convertire i valori int in BigInteger per poi moltiplicarli con se stessi utilizzando il metodo multiply (e get() è stato aggiunto per ottenere un oggetto dal wrapper opzionale ). Se eseguiamo uno di questi tre metodi con un argomento di 100, eviteremo un overflow dello stack e otterremo il risultato corretto:
9332621544394415268169923885626670049071596826438162146859296389521759999322991560894146397615651828625369792082722375825 11852109168640000000000000000000000000
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION