简体   繁体   中英

Select all combinations of elements

There is a list of MyOption elements:

class MyOption{
   List<Integer> listElements;
}

then I have two values allElements and selectedElements . The first is size of listElements and the second means how many list's items have value=0(others are null). I have to get List<MyOption> which every combination of notnull elements. I know that there are always

( allElements! / (selectedElements! * (allElements - selectedElements)! ) combinations.

For example, for allElements=3 and selectedElements=1 there are: 3!/(1!*(3-1))! = 3 3!/(1!*(3-1))! = 3 combinations ( listElements has size 3 and List<MyOption> has size 3 too):

0      null   null
null     0    null
null   null    0

and the second example for allElements=4 and selectedElements=2 , there are 6 combinations:

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

How is it possible to get all of them when I know allElements and selectedElements ?

There is a recursive definition of the binomial coefficient which yields a solution to your problem:

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);
}

Note: this is an easy to understand approach which will work fine for small inputs, there are more efficient implementations.

Here is one possible solution using recursion.

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);
}

In c++, you may use std::next_permutation , something like:

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

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

Demo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM