1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Java】組み合わせを実装してみた。

Last updated at Posted at 2020-08-03

数学の組み合わせを Java で実装してみた

異なるn個の中から異なるr個とる組み合わせを Java で実装してみました。
r個の数だけループする実装は見たことがありますが、
r個が変わっても大丈夫なようにしたくていろいろ考えました。

ソースコード

下記コードは 5個 の中から 3個 とるようになっています。

import java.util.ArrayList;
import java.util.List;

public class Trial {

    public static void main(String[] args) {
        Trial me = new Trial();
        me.exec(args);
    }

    public void exec(String[] args) {
        // 文字列の配列
        String[] strArray = new String[] { "a", "b", "c", "d", "e" };
        // 組み合わせを取得
        String[][] combinations = getCombinations(strArray, 3);
        // 結果出力
        for (String[] combination : combinations) {
            for (String str : combination) {
                System.out.print("  " + str);
            }
            System.out.println();
        }
    }

    private String[][] getCombinations(String[] strArray, int selectCount) {
        // 結果を詰める用のリスト
        List<String[]> list = new ArrayList<>();
        // ちょいちょい使うので変数に保持
        int len = strArray.length;
        // 配列の長さから2進数での最大値を求める。
        int dec = 0;
        for (int i = 0; i < len; i++) {
            dec += Math.pow(2, i);
        }
        // 最大値からデクリメントしていく。
        for (int num = dec; 0 < num; num--) {
            // 2進数表記の文字列にする。(0埋めはされない)
            String bin = Integer.toBinaryString(num);
            if (!isCombination(bin, selectCount)) {
                // 1 の数が選択数と一致しない場合は無視する。
                continue;
            }
            int j = bin.length() - 1;
            int tmplen = len - bin.length();
            String[] combination = new String[selectCount];
            int idx = selectCount - 1;
            for (int i = len - 1; tmplen <= i; i--) {
                if (bin.charAt(j--) == '1') {
                    combination[idx--] = strArray[i];
                }
            }
            list.add(combination);
        }
        return list.toArray(new String[0][0]);
    }

    private boolean isCombination(String str, int selectCount) {
        int sum = 0;
        for (int i = 0; i < str.length(); i++) {
            sum += Character.getNumericValue(str.charAt(i));
        }
        if (sum == selectCount) {
            return true;
        }
        return false;
    }
}

実行結果

  a  b  c
  a  b  d
  a  b  e
  a  c  d
  a  c  e
  a  d  e
  b  c  d
  b  c  e
  b  d  e
  c  d  e

5個から3個をとる組み合わせは、5! / (2! * (5 - 2)!) = 10
たぶん合ってる。

最後に

パフォーマンスや大きな数字を扱うことを考えると改善の余地は大いにあると思います。

以上

1
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?