CodeGym /Blog Java /Aleatoriu /Program Java pentru factorial
John Squirrels
Nivel
San Francisco

Program Java pentru factorial

Publicat în grup
Astăzi vom vorbi despre factoriali și despre cele mai comune modalități de a găsi factorii. Aceasta este una dintre cele mai de bază funcții pe care un programator trebuie să le cunoască și să poată lucra. Ei bine, să începem. Factorialul numărului n, notat cu n!, este valoarea produsului (înmulțirii) tuturor numerelor naturale de la 1 la n. Iată cum arată (să vă reîmprospătăm cunoștințele de matematică):
1! = 1 2! = 1 * 2 = 2 3! = 1 * 2 * 3 = 6 4! = 1 * 2 * 3 * 4 = 24 5! = 1 * 2 * 3 * 4 * 5 = 120
Și mai există o regulă mică pentru 0:
!0 = 1
Dacă vrem să calculăm diferența dintre 6! si 4!:
6!-4! = 1⋅2⋅3⋅4⋅5⋅6 - 1⋅2⋅3⋅4 = 720 - 24 = 696
Să vedem cum ar arăta acest lucru atunci când este implementat în programare. Vom explora câteva moduri de a face calcule factoriale în Java.

Soluție obișnuită în program factorial

Iată un program factorial simplu care utilizează bucla:

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);    
 }  
}
Ieșirea noastră pe consolă va fi:
Factorialul lui 7 este: 5040
Și încă un exemplu pentru a rezolva lucrurile:

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;
}
Nimic dificil aici: folosim numărul trecut ca mărime a buclei noastre, în care înmulțim cu toate numerele anterioare până ajungem la f. Și în principal:

System.out.println(getFactorial(6) - getFactorial(4));
Testând codul, vedem că obținem rezultatul dorit: 696.

Solutie recursiva

Recursiunea are loc atunci când o metodă se autoapelează. O astfel de metodă se numește metodă recursivă. De regulă, este format din două părți:
  1. O condiție de terminare - când condiția de terminare este îndeplinită, metoda ar trebui să înceteze să se mai apeleze și să înceapă să transmită valori în sus. La urma urmei, dacă nu există nicio condiție de terminare, atunci vom avea o buclă infinită, metoda apelându-se în mod repetat până când obținem o StackOverflowError .
  2. Indiferent de logică pe care o necesită situația, plus un apel recursiv, dar cu o valoare de intrare diferită.
Găsirea factorialului în Java este un exemplu perfect de utilizare a recursiunii:

public static int getFactorial(int f) { // finding factorial of number using recursive solution
  if (f <= 1) {
     return 1;
  }
  else {
     return f * getFactorial(f - 1);
  }
}
Condiția noastră de terminare a recursiunii va fi atunci când ajungem la 1. Dacă parametrul nu este 1, atunci înmulțim valoarea curentă cu rezultatul următorului apel recursiv la metoda (căreia îi trecem valoarea curentă minus 1).

Soluție cu un flux

Oricine nu este familiarizat cu funcționalitatea Java Stream sau oricine dorește să-și împrospătească memoria, va beneficia de citirea despre aici .

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();
  }
}
Aici folosim clasa specială IntStream , care ne oferă capabilități suplimentare atunci când lucrăm cu un flux de valori int. Pentru a crea un astfel de flux, folosim metoda sa statică rangeClosed , care generează valori de la 2 la f, inclusiv, în trepte de 1. În continuare, folosim metoda reduce pentru a combina toate valorile. Mai precis, îi arătăm cum vrem să combinăm valorile. În cele din urmă, obținem valoarea rezultată folosind metoda terminal getAsInt .

Folosind BigInteger

În Java, clasa BigInteger este adesea folosită pentru a gestiona numere, în special numere MARI. Într-adevăr, dacă folosim int , atunci factorialul maxim pe care îl putem gestiona fără pierderi de date este 31. Pentru tipul de date lung , factorialul maxim este 39. Dar dacă avem nevoie de factorialul de 100? Să adaptăm soluțiile anterioare la BigInteger.Programul Java pentru factorial - 2

Soluție obișnuită


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;
}
Algoritmul este în esență același, dar aici folosim capacitățile lui BigInteger: BigInteger.ONE este valoarea de pornire 1, iar multiplicly() este folosit pentru a multiplica valoarea factorială anterioară și numărul curent.

Solutie recursiva


public static BigInteger getFactorial(int f) {
  if (f <= 1) {
     return BigInteger.valueOf(1);
  }
  else {
     return BigInteger.valueOf(f).multiply(getFactorial(f - 1));
  }
}
Logica generală a soluției nu se schimbă, cu excepția faptului că sunt adăugate unele metode pentru lucrul cu BigInteger.

Soluție cu un flux


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();
  }
}
Totul este în esență la fel, dar cu BigInteger. Clasa Stream ne oferă metoda mapToObj , pe care o folosim pentru a converti valorile int în BigInteger pentru a le înmulți apoi cu ele însele folosind metoda multiplicare (și get() a fost adăugat pentru a obține un obiect din wrapper -ul Opțional ). Dacă rulăm oricare dintre aceste trei metode cu un argument de 100, atunci vom evita o depășire a stivei și vom obține rezultatul corect:
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976189414639761862828629638952 1185210916864000000000000000000000000
Comentarii
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION