此答案将打印所有组合,不使用递归,但如果组合总数超过Long.MAX_VALUE,则会失败。由于打印这么多行无论如何都不会结束,这不是一个真正的问题。
要按顺序打印组合,请考虑一个递增的数字,其中数字的每个数字都是相应子列表的索引。
示例(使用问题列表):
000: blue 1 dog
001: blue 1 cat
002: blue 1 fish
003: blue 1 bird
010: blue 2 dog
...
121: red 3 cat
122: red 3 fish
123: red 3 bird
每个“数字”在到达相应子列表的末尾时都会翻转,例如最后一个子列表只有 4 个元素,所以 digit 从 3 翻转到 0。
注意:“数字”的计数可以大于 9。请考虑使用十六进制表示的一种方式。
现在,位数也是动态的,即外部列表的大小。使用简单循环的一种方法是计算组合的总数 (2 * 3 * 4 = 24),然后使用除法和余数计算位数。
例子:
Combination #10 (first combination is #0):
10 % 4 = 2 (last digit)
10 / 4 % 3 = 2 % 3 = 2 (middle digit)
10 / 4 / 3 % 2 = 0 % 2 = 0 (first digit)
Digits: 022 = blue 3 fish
为了解决这个问题,我们首先构建一个除数数组,例如div[] = { 12, 4, 1 },求组合总数(24)。
long[] div = new long[array.length];
long total = 1;
for (int i = array.length - 1; i >= 0; i--) {
div[i] = total;
if ((total *= array[i].length) <= 0)
throw new IllegalStateException("Overflow or empty sublist");
}
现在我们可以遍历组合并打印结果:
for (long combo = 0; combo < total; combo++) {
for (int i = 0; i < array.length; i++) {
int digit = (int) (combo / div[i] % array[i].length);
if (i != 0)
System.out.print(' ');
System.out.print(array[i][digit]);
}
System.out.println();
}
问题输入:
String[][] array = {{"blue", "red"}, {"1", "2", "3"}, {"dog","cat", "fish", "bird"}};
我们得到以下输出:
blue 1 dog
blue 1 cat
blue 1 fish
blue 1 bird
blue 2 dog
blue 2 cat
blue 2 fish
blue 2 bird
blue 3 dog
blue 3 cat
blue 3 fish
blue 3 bird
red 1 dog
red 1 cat
red 1 fish
red 1 bird
red 2 dog
red 2 cat
red 2 fish
red 2 bird
red 3 dog
red 3 cat
red 3 fish
red 3 bird
它可以处理任何子数组的组合,例如有 4 个大小分别为 2、3、2 和 2 的子数组:
String[][] array = {{"small", "large"}, {"black", "tan", "silver"}, {"lazy", "happy"}, {"dog", "cat"}};
small black lazy dog
small black lazy cat
small black happy dog
small black happy cat
small tan lazy dog
small tan lazy cat
small tan happy dog
small tan happy cat
small silver lazy dog
small silver lazy cat
small silver happy dog
small silver happy cat
large black lazy dog
large black lazy cat
large black happy dog
large black happy cat
large tan lazy dog
large tan lazy cat
large tan happy dog
large tan happy cat
large silver lazy dog
large silver lazy cat
large silver happy dog
large silver happy cat