技術メモ

神奈川在住のITエンジニアの備忘録。おもにプログラミングやネットワーク技術について、学んだことを自分の中で整理するためにゆるゆると書いています。ちゃんと検証できていない部分もあるのでご参考程度となりますが、誰かのお役に立てれば幸いです。

Javaで、組み合わせ、順列、階乗を計算する。

競技プログラミングの問題を解く際、組み合わせ(nCr)、順列(nPr)、階乗(n!) の計算を行うことがちょくちょくあるので、今後の時短のため以下のメソッドを作成した。

    // nCr を計算する。
    // 計算結果は int max を超えやすいので long 型としている。
    // long 型を超えそうな場合は BigInteger を使用する。
    long calcCombination(int n, int r) {
        if (n < 0 || r < 0) {
            throw new IllegalArgumentException("Arguments must be 0 and over.");
        }
        else if (n == r || r == 0) {
            return 1;
        }
        else if (n < r) {
            return 0;
        }
        else {
            long result = 1;
            for (int i = 1; i <= r; i++) {
                result = result * (n - i + 1) / i;
            }
            return result;
        }
    }

    // nPr を計算する。
    long calcPermutation(int n, int r) {
        if (n < 0 || r < 0) {
            throw new IllegalArgumentException("Arguments must be 0 and over.");
        }
        else if (r == 0) {
            return 1;
        }
        else if (n < r) {
            return 0;
        }
        else {
            long result = 1;
            for (int i = 1; i <= r; i++) {
                result = result * (n - i + 1);
            }
            return result;
        }
    }

    // n! を計算する。
    long calcFactorial(int n) {
        if (n < 0) {
            throw new IllegalArgumentException("Argument must be 0 and over.");
        }
        else {
            long result = 1;
            for (int i = n; i >= 1; i--) {
                result = result * i;
            }
            return result;
        }
    }

上記では、nC0 や nP0 の計算結果は 1 としている。これは、ネットでいろいろ調べたところ、「何も選ばない」という1通りがあるという解釈になるそうなのでそうした。また、0Cr や 0Pr (r ≠ 0) については、選ぶ方法がないので計算結果は 0 としている。