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