Generate all possible combinations

Typical goal is to enumerate all possible combinations say of k elements chosen from a set of n elements (with k ≤ n). The standard combinatorics experssion for the number of such subsets is "n choose k". As we did for permutations, we will focus on the special case where the data set are numbers from 0 to n-1. As an example, here is the lexicographical enumeration of all ten ways of selecting 3 out of 5 objects.
0 1 2
0 1 3
0 1 4
0 2 3
0 2 4
0 3 4
1 2 3
1 2 4
1 3 4
2 3 4

If working with some other sequence of data values, it is possible to consider mutating that dirctly, but we will rely on an indirect approach based on the above permutations of the indices from 0, ..., n-1. If the original values are stored in data and we create the sequence comb of the k indicies, then the item with index j in the permutated data set would be data[perm[j]].


C++

It would be great if the standard library had a function next_combination, using a similar design as that of the next_permutation function, but they do not (in part, because there is no stateless way to identify what the value of "n" is seeing only one combination.

Instead, we suggest the following function, having a similar design but with the value of n being sent as an additional parameter.

template <typename BI>
bool next_combination(BI first, BI last, int n) {
  BI walk(last);
  int val(n);

  do {
    if (*(--walk) < --val) {         // punctuate this correctly!                                                         
      val = *walk + 1;
      while (walk != last) {
        *(walk++) = val++;           // punctuate this correctly!                                                           
      }
      return true;
    }
  } while (walk != first);

  return false;                      // failed                                                       
}

To get all combinations, you should start with the combination 0, 1, ..., k-1 and then call the function to advance it. typically start with the elements in sorted order (or re-sort them if necessary). As a typical example, here is how to get all combination of k numbers from the set {0, ..., n-1}.

  int comb[k];
  for (int j=0; j<k; j++)  comb[j] = j;

  do {
     // process combination
  } while ( next_combination(comb, comb+k, n) );

Java

Can do same thing, although will need to rewrite it properly to match the conventions for iterating collections.
Michael Goldwasser
Last modified: Wednesday, 01 September 2010