组合java的组合

时间:2010-09-26 22:42:44

标签: java algorithm math combinatorics combinations

我需要在JAVA中找到组合的组合。

我在课堂上有6名学生。其中,我需要组成4人组合,每组我可以选择2人的亲密团体。

我必须确保没有双打(顺序无关紧要)。并且需要打印4人组。

然而,这是困难的部分:

所以用数字定义学生:

如果我打印 1234作为其中一种组合,那么我不能打印1256,因为{{1 }}出现在121234中。

如何用Java编写?

EDITED

([1,2,3,4,5],3,2)的输出将是:

  1. 不重复的组合(n = 5,r = 3) {1,2,3} {1,2,4} {1,2,5} {1,3,4} {1,3,5} {1,4,5} {2,3,4} { 2,3,5} {2,4,5} {3,4,5}

  2. 删除2个元素的重复组,只留下我: 1256(我删除了组合为12,13,23,45,14,15的组,因为它们已经出现在我找到的前两个组中。

2 个答案:

答案 0 :(得分:1)

好的,这是您描述的过程的简单模拟。但我使用二进制数来表示集合,它使操作更容易。例如,数字19是二进制形式的10011:它意味着学生0,3和4被选中(这些位置有1个)。

首先是一个小帮手。

// return all subsets of 'set', having size 'subsetSize'
Set<Integer> allSubsets(int set, int subsetSize) {
    Set<Integer> result = new HashSet<Integer>();
    if (subsetSize == 0) {
        result.add(0);
        return result;
    }
    if (set == 0) {
        return result;
    }

    // check if 1st element is present
    if (set % 2 == 1) {
        // use 1st element, one less element to collect
        for (Integer i : allSubsets(set / 2, subsetSize - 1)) {
            result.add(i * 2 + 1);
        }
    }
    // not use 1st element
    for (Integer i : allSubsets(set / 2, subsetSize)) {
        result.add(i * 2);
    }

    return result;
}

主程序。欢迎提出建议。

    int N = 5;
    int M = 3;
    int Z = 2;

    List<Integer> result = new ArrayList<Integer>();

    // get all groups of M elements from 'wholeSet'
    int wholeSet = (1 << N) - 1;
    for (int s : allSubsets(wholeSet, M)) {
        // Check all subsets of 'Z' elements from set 's'
        boolean valid = true;
        for (int t : allSubsets(s, Z)) {
            // check if this Z-element subset already was used
            for (int past : result) {
                // check if 't' is subset of 'past' set
                if ((past|t) == past) {
                    valid = false;
                    break;
                }
            }
            if (!valid) {
                break;
            }
        }

        if (valid) {
            // none of Z-element subsets of 's' were used before
            result.add(s);
        }
    }

但是对于大输入,可能需要改进(如memoization)。但就目前而言,由于你没有说出你期望的输入,我认为这已经足够了。

答案 1 :(得分:0)

想象一下,你有一个Student对象,它等于比较他们的Primarykey。在您的示例中,学生1将返回1,2,将返回2,依此类推。

将它们全部放入集合中,这将确保没有双倍。

虽然按4然后按2进行迭代,但会返回你想要的结果。