Java で階乗を計算する方法
- Java の反復法を使用して階乗を取得する
- Java で再帰的手法を用いて階乗を求める
- Java で動的アプローチを使用して階乗を求める
- Java で Apache Commons を使用して階乗を検索する
- Java 8 ストリームを使用して階乗を検索
-
Java で
BigInteger
を使用して階乗を検索 -
BigIntegerMath
ライブラリを使用して階乗を検索
このチュートリアルでは、Java で階乗を計算するためのメソッドとコード例を紹介します。
数 n
の階乗は、1
と n
の間のすべての自然数の乗算です。このチュートリアルでは、数値の階乗を計算するさまざまな方法を説明します。
まず、20
以下の数値の階乗を計算する方法を見ていきます。この分離は、Java の長いデータ型の範囲が限られているためです。
20
を超える数値の階乗は大きすぎて、ロングの範囲に収まりません。
Java の反復法を使用して階乗を取得する
この例では、長い型の変数 store_fact
を作成し、それを 1
で初期化しました。
次に、1
から階乗が計算される数値までのすべての整数をループし、ループ変数値に store_fact
値を乗算します。計算された値を store_fact
変数に保存し、ループ変数を更新しました。
上記のアルゴリズムをより明確にするために、次のように書くことができます。
n
を初期化しますstore_fact = 1
を初期化しますfor i = 1
からn
を実行しますstore_fact = store_fact*n
- インクリメント
i
store_fact
を返します
上記のアルゴリズムでは、store_fact
変数は次のように n
の階乗を格納します。
- 最初の反復後:
store_value = 1 = 1!
- 2 回目の反復後:
store_value = 1 X 2 = 2!
- 3 回目の反復後:
store_value = 1 X 2 X 3 = 3!
- n 回目の反復後:
store_value = 1 X 2 X 3 X 4 ........ Xn = n!
上記のアルゴリズムのコード例を見てみましょう。
import java.util.Scanner;
public class SimpleTesting {
static long factCalculator(int n) {
long store_fact = 1;
int i = 1;
while (i <= n) {
store_fact = store_fact * i;
i++;
}
return store_fact;
}
public static void main(String args[]) {
int number;
Scanner scan = new Scanner(System.in);
System.out.println("Enter a number: ");
number = scan.nextInt();
System.out.println(factCalculator(number));
}
}
出力:
Enter a number:
4
24
Java で再帰的手法を用いて階乗を求める
上記の反復法は、任意の数の階乗を求めるための再帰法に変換できます。この方法では、基本ケースを次のように取ります。
if (n == 0 || n == 1) {
return 1;
}
基本条件が満たされない場合は、次を返します。
n* factCalculator(n - 1);
以下のコード例を見てみましょう。階乗を求めるために、再帰メソッド factCalculator()
を使用しました。
import java.util.*;
public class SimpleTesting {
static long factCalculator(int n) {
if (n == 0 || n == 1) {
return 1;
} else {
return n * factCalculator(n - 1);
}
}
public static void main(String args[]) {
int number;
Scanner scan = new Scanner(System.in);
System.out.println("Enter a number: ");
number = scan.nextInt();
System.out.println(factCalculator(number));
}
}
出力:
Enter a number:
4
24
Java で動的アプローチを使用して階乗を求める
動的計画法を使用して、数値の階乗を計算することもできます。この方法は、小さい数の階乗を格納し、それらの階乗を使用して大きい数の階乗を計算するため、他の方法よりも高速です。
例えば:
- 5! = 5 X 4!
- 4! = 4 X 3!
- 3! = 3 X 2!
- 2! = 2 X 1!
- 1! = 1 X 0!
- 0! = 1
このメソッドでは、ルックアップテーブルを作成します。このテーブルには、0
から 20
までの数値の階乗が格納されます。
ルックアップテーブルを 20
まで作成したのは、それが階乗の long を格納できる最大の数だからです。0!
を初期化しました 1
として。
次に、値 0!
を使用しました 1!
、1!
の値を計算するには 2!
を計算するには等々。以下のコードを見てください。
import java.util.*;
public class SimpleTesting {
static long[] factCalculator() {
long[] fact_table = new long[21];
fact_table[0] = 1;
for (int i = 1; i < fact_table.length; i++) {
fact_table[i] = fact_table[i - 1] * i;
}
return fact_table;
}
public static void main(String args[]) {
long[] table = factCalculator();
int number;
Scanner scan = new Scanner(System.in);
System.out.println("Enter a number: ");
number = scan.nextInt();
System.out.println(table[number]);
}
}
出力:
Enter a number:
5
120
Java で Apache Commons を使用して階乗を検索する
Apache Commons Math
ライブラリを使用する場合は、factorial()
メソッドで CombinatoricsUtils
クラスを使用します。これは、任意の数の階乗を計算するための組み込みの方法です。
このメソッドによって返される値は long 型です。したがって、20
より大きい数の階乗を計算することはできません。以下の例を参照してください。
import java.util.Scanner;
import org.apache.commons.math3.util.CombinatoricsUtils;
public class SimpleTesting {
static long factCalculator(int n) {
return CombinatoricsUtils.factorial(n);
}
public static void main(String args[]) {
int number;
Scanner scan = new Scanner(System.in);
System.out.println("Enter a number: ");
number = scan.nextInt();
System.out.println(factCalculator(number));
}
}
出力:
Enter a number:
5
120
Java 8 ストリームを使用して階乗を検索
Java 8 ストリーム API を使用して、数値の階乗を計算することもできます。まず、1
から n
までの数値のストリームを作成します。ここで、n
は階乗が計算される数値です。
次に、reduce メソッドを使用して、要素に対して縮小操作を実行します。単位元として 1
を渡し、結合法則関数として乗算を渡しました。
以下のコードを見てください。
import java.util.*;
import java.util.stream.LongStream;
public class SimpleTesting {
static long factCalculator(int n) {
return LongStream.rangeClosed(1, n).reduce(1, (long num1, long num2) -> num1 * num2);
}
public static void main(String args[]) {
int number;
Scanner scan = new Scanner(System.in);
System.out.println("Enter a number: ");
number = scan.nextInt();
System.out.println(factCalculator(number));
}
}
出力:
Enter a number:
5
120
反復または再帰メソッドよりも reduce()
関数を使用することには大きな利点があります。要素の処理に使用される関数が結合法則である場合、reduce()
操作は並列化可能です。
ここで、20
を超える数値の階乗を計算します。
Java で BigInteger
を使用して階乗を検索
BigInteger
クラスは、プリミティブデータ型の範囲を超える非常に大きな数を処理するために使用されます。BigInteger
を使用して、20
より上の数値の階乗の値を格納できます。
以下の例を参照してください。
import java.math.BigInteger;
import java.util.Scanner;
public class SimpleTesting {
static BigInteger factCalculator(int n) {
BigInteger store_fact = BigInteger.ONE;
for (int i1 = 2; i1 <= n; i1++) {
store_fact = store_fact.multiply(BigInteger.valueOf(i1));
}
return store_fact;
}
public static void main(String args[]) {
int number;
Scanner scan = new Scanner(System.in);
System.out.println("Enter a number: ");
number = scan.nextInt();
System.out.println(factCalculator(number));
scan.close();
}
}
出力:
Enter a number:
50
30414093201713378043612608166064768844377641568960512000000000000
*
演算子を使用して BigInteger
を乗算することはできないため、multiply()
関数を使用します。このメソッドは、long の代わりに BigInteger
を使用することを除いて、反復メソッドと同じです。
BigIntegerMath
ライブラリを使用して階乗を検索
BigIntegerMath
ライブラリには、数値の階乗を計算するために使用できる factorial()
メソッドが組み込まれています。これは静的メソッドであり、long 型の値を返します。
以下の例を参照してください。
import com.google.common.math.BigIntegerMath;
import java.util.*;
public class SimpleTesting {
static long factCalculator(int n) {
return BigIntegerMath.factorial(n);
}
public static void main(String args[]) {
int number;
Scanner scan = new Scanner(System.in);
System.out.println("Enter a number: ");
number = scan.nextInt();
System.out.println(factCalculator(number));
}
}
出力:
Enter a number:
50
30414093201713378043612608166064768844377641568960512000000000000