In fact, there is a more general method that also answers the question "how to change the number of cycles at runtime?".
General question
We are looking for a way to implement something equivalent to this:
for (i1 = 0; i1 < k1; i1++) { for (i2 = 0; i2 < k2; i2++) { for (i3 = 0; i3 < k3; i3++) { ... for (in = 0; in < kn; in++) { f(x1[i1], x2[i2], ... xn[in]); } ... } } }
where n is specified at runtime, and f is a function that takes a list of n parameters, processing the current n-tuple.
Common decision
There is a general solution based on the concept of recursion .
This is one implementation that creates the desired behavior:
void process(int idx, int n, int[][] x, int[] k, Object[] ntuple) { if (idx == n) { // we have a complete n-tuple, // with an element from each of the n arrays f(ntuple); return; } // this is the idx'th "for" statement for (int i = 0; i < k[idx]; i++) { ntuple[idx] = x[idx][i]; // with this recursive call we make sure that // we also generate the rest of the for's process(idx + 1, n, x, k, ntuple); } }
The function assumes that the n arrays are stored in the matrix x , and the first call should look like this:
process(0, n, x, k, new Object[n]);
Practical considerations
The solution above has high complexity (this is O (k 1 β
k 2 β
..β
k n )), but sometimes you can avoid going to the deepest loop.
In fact, in the specific task mentioned in this article (which requires the summation of common elements across all arrays), we can skip the creation of some sets, for example. if already x 2 [i 2 ] β x 1 [i 1 ].
In a recursive solution, these situations can be easily trimmed. The specific code for this problem is likely to look like this:
void process(int idx, int n, int[][] x, int[] k, int value) { if (idx == n) { // all elements from the current tuple are equal to "value". // add this to the global "sum" variable sum += value; return; } for (int i = 0; i < k[idx]; i++) { if (idx == 0) { // this is the outer "for", set the new value value = x[0][i]; } else { // check if the current element from the idx'th for // has the same value as all previous elements if (x[idx][i] == value) { process(idx + 1, n, x, k, value); } } } }