1. ภาพรวม
ได้รับจำนวนเต็มไม่เป็นลบn , แฟกทอเป็นผลิตภัณฑ์ของจำนวนเต็มบวกทั้งหมดน้อยกว่าหรือเท่ากับn
ในการกวดวิชาอย่างนี้เราจะสำรวจวิธีการที่แตกต่างกันในการคำนวณปัจจัยสำหรับจำนวนที่กำหนดใน Java
2. แฟคทอเรียลสำหรับตัวเลขสูงสุด 20
2.1. Factorial โดยใช้for Loop
มาดูอัลกอริธึมแฟกทอเรียลพื้นฐานโดยใช้for loop:
public long factorialUsingForLoop(int n) { long fact = 1; for (int i = 2; i <= n; i++) { fact = fact * i; } return fact; }
การแก้ปัญหาดังกล่าวข้างต้นจะทำงานที่ดีสำหรับตัวเลขถึง 20 แต่ถ้าเราลองอะไรที่ใหญ่กว่า 20 มันก็จะล้มเหลวเพราะผลลัพธ์จะใหญ่เกินกว่าที่จะใส่เข้าไปในระยะยาวทำให้เกิดการล้น
เรามาดูกันอีกเล็กน้อยโดยสังเกตว่าแต่ละรายการจะใช้ได้กับจำนวนน้อยเท่านั้น
2.2. Factorial โดยใช้ Java 8 Streams
เรายังสามารถใช้ Java 8 Stream API เพื่อคำนวณแฟกทอเรียลได้อย่างง่ายดาย:
public long factorialUsingStreams(int n) { return LongStream.rangeClosed(1, n) .reduce(1, (long x, long y) -> x * y); }
ในโปรแกรมนี้ครั้งแรกที่เราใช้LongStreamย้ำผ่านตัวเลขระหว่าง 1 และn จากนั้นเราใช้การลด ()ซึ่งใช้ค่าเอกลักษณ์และฟังก์ชันตัวสะสมสำหรับขั้นตอนการลด
2.3. แฟกทอเรียลโดยใช้การเรียกซ้ำ
มาดูอีกตัวอย่างของโปรแกรมแฟกทอเรียลคราวนี้ใช้การเรียกซ้ำ:
public long factorialUsingRecursion(int n) { if (n <= 2) { return n; } return n * factorialUsingRecursion(n - 1); }
2.4. Factorial โดยใช้ Apache Commons Math
Apache Commons Math มีคลาสCombinatoricsUtils ที่มีวิธีการแฟกทอเรียลคงที่ซึ่งเราสามารถใช้เพื่อคำนวณแฟกทอเรียลได้
ในการรวม Apache Commons Math เราจะเพิ่มการพึ่งพาcommons-math3ในpomของเรา:
org.apache.commons commons-math3 3.6.1
มาดูตัวอย่างการใช้คลาสCombinatoricsUtils :
public long factorialUsingApacheCommons(int n) { return CombinatoricsUtils.factorial(n); }
สังเกตว่าประเภทการส่งคืนนั้นยาวเช่นเดียวกับโซลูชันที่ผลิตเองในบ้านของเรา
นั่นหมายความว่าที่นี่ว่าถ้าราคาคำนวณเกินLong.MAX_VALUEเป็นMathArithmeticExceptionจะโยน
เพื่อให้ได้ผลตอบแทนที่มากขึ้นเราจำเป็นต้องมีผลตอบแทนประเภทอื่น
3. แฟคทอเรียลสำหรับตัวเลขที่มากกว่า 20
3.1. Factorial โดยใช้BigInteger
ตามที่กล่าวไว้ก่อนหน้านี้ประเภทข้อมูลแบบยาวสามารถใช้สำหรับแฟกทอเรียลสำหรับn <= 20เท่านั้น
สำหรับค่าขนาดใหญ่ของn , เราสามารถใช้BigIntegerระดับจากjava.mathแพคเกจที่สามารถถือค่าถึง2 ^ Integer.MAX_VALUE :
public BigInteger factorialHavingLargeResult(int n) { BigInteger result = BigInteger.ONE; for (int i = 2; i <= n; i++) result = result.multiply(BigInteger.valueOf(i)); return result; }
3.2. Factorial การใช้ Guava
ห้องสมุด Guava ของ Google ยังมีวิธียูทิลิตี้สำหรับการคำนวณแฟกทอเรียลสำหรับจำนวนที่มากขึ้น
ในการรวมไลบรารีเราสามารถเพิ่มguava dependency ให้กับpomของเรา:
com.google.guava guava 25.1-jre
ตอนนี้เราสามารถใช้วิธีการแฟกทอเรียลแบบคงที่จากคลาสBigIntegerMathเพื่อคำนวณแฟกทอเรียลของจำนวนที่กำหนด:
public BigInteger factorialUsingGuava(int n) { return BigIntegerMath.factorial(n); }
4. สรุป
ในบทความนี้เราได้เห็นวิธีการคำนวณแฟกทอเรียลโดยใช้ core Java และไลบรารีภายนอกสองสามวิธี
เราแก้ปัญหาที่เห็นครั้งแรกโดยใช้ยาวชนิดข้อมูลสำหรับการคำนวณ factorials ของตัวเลขได้ถึง20 จากนั้นเราเห็นสองวิธีในการใช้BigIntegerสำหรับตัวเลขที่มากกว่า 20
โค้ดที่นำเสนอในบทความนี้มีอยู่บน Github