คำนวณ Factorial ใน Java

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