Вот стандартный рекурсивный генератор:
import java.util.Arrays;
//...
static void generate(int... limits) {
generate(new int[limits.length], limits, 0);
}
static void generate(int[] arr, int[] limits, int n) {
if (n == limits.length) {
System.out.println(Arrays.toString(arr));
} else {
for (int i = 0; i <= limits[n]; i++) {
arr[n] = i;
generate(arr, limits, n + 1);
}
}
}
//....
generate(1, 2);
/* prints
[0, 0]
[0, 1]
[0, 2]
[1, 0]
[1, 1]
[1, 2]
*/
Это работает так же, как если бы вы написали переменное число вложенных циклов. С рекурсией вам нужно написать только один цикл, и он может иметь переменную глубину вложения (бесконечно, если вы не осторожны!).
Существует также итерационная, т.е. нерекурсивная версия:
static void generateI(int... limits) {
int[] arr = new int[limits.length];
int n;
do {
System.out.println(Arrays.toString(arr));
n = limits.length - 1;
while (n >= 0 && arr[n] == limits[n]) {
arr[n] = 0;
n--;
}
if (n >= 0) arr[n]++;
} while (n >= 0);
}
Это работает во многом так же, как приращение на 1 работает в двоичной арифметике (или на любой другой базе), за исключением того, что каждая позиция имеет свой предел.
Например, в базе 10 вот как вы увеличиваете:
12399
^ (is highest digit, therefore set to 0, move left)
12390
^ (is highest digit, therefore set to 0, move left)
12400
^ (not the highest digit, add 1, DONE!)