Howto create combinations of several vectors without hardcoding loops in C++?

You can implement this like an odometer, which leads to the following (works for different-sized vectors):

Say you have K vectors in an array v: v[0], v[1], ... v[K-1]

Keep an array of iterators it (size K) into your vectors, starting with it[i] = v[i].begin(). Keep incrementing it[K-1] in a loop. When any iterator hits the end() of the corresponding vector, you wrap it around to begin() and increment the previous iterator also (so when it[K-1] wraps around, you increment it[K-2]). These increments may “cascade” so you should do them in a loop backwards. When it[0] wraps around, you’re done (so your loop condition could be something like while (it[0] != v[0].end())

Putting all that together, the loop that does the work (after setting up the iterators) should be something like:

while (it[0] != v[0].end()) {
  // process the pointed-to elements

  // the following increments the "odometer" by 1
  ++it[K-1];
  for (int i = K-1; (i > 0) && (it[i] == v[i].end()); --i) {
    it[i] = v[i].begin();
    ++it[i-1];
    }
  }

If you’re interested in complexity, the number of iterator increments that get performed is easy to calculate. For simplicity here I’ll assume each vector is the same length N. The total number of combinations is NK. The last iterator gets incremented each time, so that is NK, and moving back through the iterators this count gets divided by N each time, so we have NK + NK-1 + … N1; this sum equals N(NK – 1)/(N-1) = O(NK). This also means that the amortized cost per-combination is O(1).

Anyway, in short, treat it like an odometer spinning its digit wheels.

Leave a Comment