Given a list of size n, Write a program that returns all possible combination of elements contained in each list.
Example:
Think of it like how you increment a number, e.g. a base 3 number would go:
000
001
002
010
011
...
222
Now think of each digit being the index into each of the nested lists. You will have as many digits as you have nested lists, i.e. the size of the outer list.
The "base" of each digit may differ, and is the size of the corresponding nested list. A "digit" can be a very large number if a nested list is large.
So, you start by creating a list of "digit", or index values, initializing them to 0
. You then print the values of the elements at those indices. You then increment the last index value, rolling over as needed, like you would a normal number, stopping when the first index value rolls over.
Here is a Java implementation using arrays of arrays, i.e. String[][]
. You can easily change to List
or >
List
if needed.
@SafeVarargs
public static void printCombos(String[] ... lists) {
if (lists.length == 0)
throw new IllegalArgumentException("No lists given");
for (String[] list : lists)
if (list.length == 0)
throw new IllegalArgumentException("List is empty");
int[] idx = new int[lists.length];
for (;;) {
// Print combo
for (int i = 0; i < lists.length; i++) {
if (i != 0)
System.out.print(' ');
System.out.print(lists[i][idx[i]]);
}
System.out.println();
// Advance to next combination
for (int i = lists.length - 1; ++idx[i] == lists[i].length; ) {
idx[i] = 0;
if (--i < 0)
return; // We're done
}
}
}
public static void main(String[] args) {
String[][] data = { { "x", "z" }, { "a", "b", "c" }, { "o", "p" } };
printCombos(data);
}
OUTPUT
x a o
x a p
x b o
x b p
x c o
x c p
z a o
z a p
z b o
z b p
z c o
z c p
If you use lists instead of arrays, then the code will use get(int)
, which may not always be good for performance, e.g. for LinkedList
.
If that is the case, replace int[] idx
with an Iterator[]
, initializing each array entry with an iterator for the corresponding list. Resetting a "digit" to 0 would then be done by retrieving a new Iterator
from the list in question.
In this case, they don't even have to be lists, but can be any kind of collection, or more specifically Iterable objects.