选择所有元素组合

时间:2017-03-18 17:51:15

标签: java c++ algorithm

有一个MyOption元素列表:

class MyOption{
   List<Integer> listElements;
}

然后我有两个值allElementsselectedElements。第一个是listElements的大小,第二个是表示有多少列表项的值= 0(其他是空的)。 我必须得到List<MyOption>每个组合的无效元素。我知道总有

( allElements! / (selectedElements! * (allElements - selectedElements)! )组合。

例如,对于allElements=3selectedElements=1,有: 3!/(1!*(3-1))! = 3组合listElements的大小为3,List<MyOption>的大小为3):

0      null   null
null     0    null
null   null    0

以及allElements=4selectedElements=2的第二个示例,共有6种组合:

0      0     null  null
0     null    0    null
0     null   null   0
null   0      0    null
null   0     null   0
null  null    0     0

当我知道allElementsselectedElements时,如何才能获得所有这些内容?

3 个答案:

答案 0 :(得分:0)

二项式系数recursive definition可以解决您的问题:

public static long choose(long allElements, long selectedElements){
    if(allElements < selectedElements)
        return 0;
    if(selectedElements == 0 || selectedElements == allElements)
        return 1;
    return choose(allElements-1,selectedElements-1)+choose(allElements-1,selectedElements);
}

注意:这是一种易于理解的方法,适用于小输入,有更高效的实现。

答案 1 :(得分:0)

这是使用递归的一种可能的解决方案。

private static void combinations(ArrayList<Integer> solution, int selectedElements, int start, ArrayList<List<Integer>> solutions) {
  if(selectedElements < 1) {
    solutions.add(new ArrayList<>(solution));
  } else {
    for(int i = start; i < solution.size() - selectedElements + 1; i++) {
      solution.set(i, 0);
      combinations(solution, selectedElements - 1, i+1, solutions);
      solution.set(i, null);
    }
  }
}
static List<List<Integer>> combinations(int allElements, int selectedElements) {
  ArrayList<List<Integer>> solutions = new ArrayList<>();
  ArrayList<Integer> solution = new ArrayList<>();
  for(int i = 0; i < allElements; i++) solution.add(null);
  combinations(solution, selectedElements, 0, solutions);
  return solutions;
}
public static void main(String[] args) {
  List<List<Integer>> solutions = combinations(4, 2);
  System.out.println(solutions);
}

答案 2 :(得分:0)

在c ++中,您可以使用std::next_permutation,例如:

std::vector<int> v {0, 0, 1, 1};

do {
    print(v);
} while (std::next_permutation(std::begin(v), std::end(v)));

Demo