我需要在JAVA中找到组合的组合。
我在课堂上有6名学生。其中,我需要组成4人组合,每组我可以选择2人的亲密团体。
我必须确保没有双打(顺序无关紧要)。并且需要打印4人组。
然而,这是困难的部分:
所以用数字定义学生:
如果我打印 1234
作为其中一种组合,那么我不能打印1256
,因为{{1 }}出现在12
和1234
中。
如何用Java编写?
EDITED
([1,2,3,4,5],3,2)的输出将是:
不重复的组合(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个元素的重复组,只留下我:
1256
(我删除了组合为12,13,23,45,14,15的组,因为它们已经出现在我找到的前两个组中。
答案 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进行迭代,但会返回你想要的结果。