CodeGym /Java blog /Véletlen /Java program faktoriálishoz
John Squirrels
Szint
San Francisco

Java program faktoriálishoz

Megjelent a csoportban
Ma a faktoriálisokról és a faktoriális megtalálásának leggyakoribb módjairól fogunk beszélni. Ez az egyik legalapvetőbb funkció, amelyet a programozónak ismernie kell, és tudnia kell dolgoznia. Nos, kezdjük. Az n szám faktoriálisa, amelyet n-ként jelölünk!, az összes természetes szám szorzatának (szorzásának) értéke 1-től n-ig. Így néz ki (frissítsük fel matematikai ismereteit):
1! = 12! = 1 * 2 = 2 3! = 1 * 2 * 3 = 6 4! = 1 * 2 * 3 * 4 = 24 5! = 1 * 2 * 3 * 4 * 5 = 120
És van még egy kis szabály a 0-hoz:
!0 = 1
Ha ki akarjuk számolni a 6 közötti különbséget! és 4!:
6!-4! = 1⋅2⋅3⋅4⋅5⋅6 - 1⋅2⋅3⋅4 = 720 - 24 = 696
Nézzük meg, hogyan nézne ki ez a programozásban megvalósítva. Megvizsgálunk néhány módszert a faktoriális számítások elvégzésére Java nyelven.

Szokásos megoldás faktoriális programban

Íme egy egyszerű faktoriális program, amely ciklust használ:

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);    
 }  
}
A kimenetünk a konzolon a következő lesz:
A 7-es faktorszám: 5040
És még egy példa a dolgok rendezésére:

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;
}
Nincs itt semmi nehéz: az átadott számot használjuk ciklusunk méretének, amelyben az összes előző számmal szorozunk, amíg el nem jutunk f-hez. És főben:

System.out.println(getFactorial(6) - getFactorial(4));
A kód tesztelése során azt látjuk, hogy a kívánt eredményt kapjuk: 696.

Rekurzív megoldás

A rekurzió akkor történik, amikor egy metódus meghívja magát. Az ilyen módszert rekurzív módszernek nevezzük. Általános szabály, hogy két részből áll:
  1. Lezáró feltétel – ha a lezárási feltétel teljesül, a metódusnak le kell állítania önmagának a hívását, és el kell kezdenie az értékeket feljebb adni. Végül is, ha nincs lezáró feltétel, akkor végtelen ciklusunk lesz, a metódus ismételten hívja magát, amíg StackOverflowError -t nem kapunk .
  2. Bármilyen logikát is igényel a helyzet, plusz egy rekurzív hívás, de más bemeneti értékkel.
A faktoriális Java nyelven való megtalálása tökéletes példa arra, hogy mikor kell rekurziót használni:

public static int getFactorial(int f) { // finding factorial of number using recursive solution
  if (f <= 1) {
     return 1;
  }
  else {
     return f * getFactorial(f - 1);
  }
}
A rekurzió befejező feltétele az lesz, ha elérjük az 1-et. Ha a paraméter nem 1, akkor az aktuális értéket megszorozzuk a metódus következő rekurzív hívásának eredményével (amelynek az aktuális értéket mínusz 1-gyel továbbítjuk).

Megoldás Stream segítségével

Aki nem ismeri a Java Stream funkcióját, vagy aki fel szeretné frissíteni a memóriáját, annak jól jön, ha itt olvashat róla .

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();
  }
}
Itt a speciális IntStream osztályt használjuk , amely további lehetőségeket biztosít számunkra, amikor int értékek folyamával dolgozunk. Egy ilyen adatfolyam létrehozásához a statikus rangeClosed metódust használjuk , amely 2-től f-ig, beleértve az értékeket is, 1-es lépésekben generál. Ezután a redukciós módszerrel kombináljuk az összes értéket. Pontosabban megmutatjuk, hogyan akarjuk egyesíteni az értékeket. Végül a kapott értéket a terminális getAsInt metódussal kapjuk meg .

BigInteger használata

A Java-ban a BigInteger osztályt gyakran használják számok, különösen BIG számok kezelésére. Valóban, ha az int -t használjuk , akkor az adatvesztés nélkül kezelhető maximum faktoriális 31. Hosszú adattípus esetén a maximum faktoriális 39. De mi van akkor, ha a 100-as faktoriálisra van szükségünk? A korábbi megoldásokat adaptáljuk BigIntegerre.Java program faktoriálishoz - 2

Hétköznapi megoldás


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;
}
Az algoritmus lényegében ugyanaz, de itt a BigInteger képességeit használjuk: a BigInteger.ONE a kezdőérték 1, a multiply() pedig az előző faktoriális érték és az aktuális szám szorzására szolgál.

Rekurzív megoldás


public static BigInteger getFactorial(int f) {
  if (f <= 1) {
     return BigInteger.valueOf(1);
  }
  else {
     return BigInteger.valueOf(f).multiply(getFactorial(f - 1));
  }
}
A megoldás általános logikája nem változik, kivéve, hogy a BigIntegerrel való munkavégzéshez néhány metódust adnak hozzá.

Megoldás Stream segítségével


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();
  }
}
Minden lényegében ugyanaz, csak a BigIntegerrel. A Stream osztály megadja nekünk a mapToObj metódust, amellyel az int értékeket BigIntegerre konvertáljuk, hogy aztán a szorzási metódussal megszorozzuk őket önmagukkal (és a get() hozzáadásával kapunk objektumot az Optional wrapperből). Ha a három módszer bármelyikét 100-as argumentummal futtatjuk, akkor elkerüljük a verem túlcsordulást, és a helyes eredményt kapjuk:
933262154439441526816992388562667004907159682643816214685929638952175999932299156089414639915608941463991560894146397615625282828272828282968264381621468592963 11852109168640000000000000000000000000
Hozzászólások
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION