Java で階乗を計算する方法

Mohammad Irfan 2023年10月12日
  1. Java の反復法を使用して階乗を取得する
  2. Java で再帰的手法を用いて階乗を求める
  3. Java で動的アプローチを使用して階乗を求める
  4. Java で Apache Commons を使用して階乗を検索する
  5. Java 8 ストリームを使用して階乗を検索
  6. Java で BigInteger を使用して階乗を検索
  7. BigIntegerMath ライブラリを使用して階乗を検索
Java で階乗を計算する方法

このチュートリアルでは、Java で階乗を計算するためのメソッドとコード例を紹介します。

n の階乗は、1n の間のすべての自然数の乗算です。このチュートリアルでは、数値の階乗を計算するさまざまな方法を説明します。

まず、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

関連記事 - Java Math