Reputation: 69259
I have made the functions already, but I'm stuck currently with the implementation. It is especially hard to think about it when it involves multiple variables.
What I want: With input [["A", "B"], ["0", "1", "2"]]
, I want as output [["A", "0"], ["A", "1"], ["A", "2"], ["B", "0"], ["B", "1"], ["B", "2"]]
. I hope that is clear enough.
My code until now:
/**
* Returns a list of all possible combinations of the entered lists.
*
* Example: [["A", "B"], ["0", "1", "2"]]
* Returns: [["A", "0"], ["A", "1"], ["A", "2"], ["B", "0"], ["B", "1"], ["B", "2"]]
*
* @param <T> The type parameter
* @param elements An array of lists
* @return All possible combinations of the entered lists
*/
public static <T> List<List<T>> createCombinations(List<T>... elements) {
int[] i = new int[elements.length];
List<List<T>> returnLists = new ArrayList<>();
for (int j = 0; j < elements.length; j++) {
}
return returnLists;
}
public static <T> List<List<T>> createCombinations(List<List<T>> elements) {
return createCombinations((List<T>[])elements.toArray());
}
EDIT: It may be a bit confusing on how I actually want to use it, but this is how:
List<List<String>> combinations = Utils.createCombinations(cocNumbers, vatNumbers, ibans);
.
Upvotes: 0
Views: 155
Reputation: 8161
A simple way to do this is a recursive approach. Have the method do a for loop for the first list to go through all its values. Each time it picks one, it calls itself with the first list removed. It then adds the value it picked to the recursive call's return value. Return a list of all these values created by the for loop.
Pseudocode:
public static <T> List<List<T>> createCombinations(List<T>... elements) {
(call non-vararg function)
}
public static <T> List<List<T>> createCombinations(List<List<T>> elements) {
if (elements is empty) {
return empty list
}
List<T> head = get first list in elements
List<T> tail = everything in elements except the first list
List<T> allCombinations = empty list
List<T> subcombinations = createCombinations(tail);
for(every value in head) {
List<T> x = copy of subcombinations with current value added to front
add x to allCombinations
}
retyrn allCombinations;
}
Upvotes: 2
Reputation: 69259
Figured it out myself eventually.
The code itself:
/**
* Returns a list of all possible combinations of the entered array of lists.
*
* Example: [["A", "B"], ["0", "1", "2"]]
* Returns: [["A", "0"], ["A", "1"], ["A", "2"], ["B", "0"], ["B", "1"], ["B", "2"]]
*
* @param <T> The type parameter
* @param elements An array of lists
* @return All possible combinations of the entered lists
*/
public static <T> List<List<T>> createCombinations(List<T>... elements) {
List<List<T>> returnLists = new ArrayList<>();
int[] indices = new int[elements.length];
for (int i = 0; i < indices.length; i++) {
indices[i] = 0;
}
returnLists.add(generateCombination(indices, elements));
while (returnLists.size() < countCombinations(elements)) {
gotoNextIndex(indices, elements);
returnLists.add(generateCombination(indices, elements));
}
return returnLists;
}
/**
* Jumps to the next index for creating combinations.
*
* This method updates the indices.
*
* @param <T> The type parameter
* @param indices The index positions
* @param elements Array of lists
*/
private static <T> void gotoNextIndex(int[] indices, List<T>... elements) {
for (int j = indices.length - 1; j >= 0; j--) {
if (indices[j] == elements[j].size() - 1) {
indices[j] = 0;
continue;
}
indices[j]++;
return;
}
}
/**
* Return a combination in the form of a list based on the current indices.
*
* @param <T> The type parameter
* @param indices The index positions
* @param elements Array of lists
* @return The combination
*/
private static <T> List<T> generateCombination(int[] indices, List<T>... elements) {
List<T> returnList = new ArrayList<>();
for (int i = 0; i < indices.length; i++) {
returnList.add(elements[i].get(indices[i]));
}
return returnList;
}
/**
* Counts the possible number of combinations in this array of lists.
*
* @param <T> The type parameter
* @param elements Array of lists
* @return Possible number of combinations
*/
private static <T> int countCombinations(List<T>... elements) {
int count = 1;
for (List<T> list : elements) {
count *= list.size();
}
return count;
}
/**
* Returns a list of all possible combinations of the entered list of lists.
*
* Example: [["A", "B"], ["0", "1", "2"]]
* Returns: [["A", "0"], ["A", "1"], ["A", "2"], ["B", "0"], ["B", "1"], ["B", "2"]]
*
* @param <T> The type parameter
* @param elements A list of lists
* @return All possible combinations of the entered lists
*/
public static <T> List<List<T>> createCombinations(List<List<T>> elements) {
return createCombinations((List<T>[])elements.toArray());
}
Example:
List<String> l1 = new ArrayList<>();
l1.add("A");
l1.add("B");
List<String> l2 = new ArrayList<>();
l2.add("0");
l2.add("1");
l2.add("2");
List<String> l3 = new ArrayList<>();
l3.add("w");
l3.add("x");
l3.add("y");
l3.add("z");
List<List<String>> combs = Utils.createCombinations(l1, l2, l3);
for (List<String> l : combs) {
System.out.println("l = " + l);
}
Example output:
l = [A, 0, w]
l = [A, 0, x]
l = [A, 0, y]
l = [A, 0, z]
l = [A, 1, w]
l = [A, 1, x]
l = [A, 1, y]
l = [A, 1, z]
l = [A, 2, w]
l = [A, 2, x]
l = [A, 2, y]
l = [A, 2, z]
l = [B, 0, w]
l = [B, 0, x]
l = [B, 0, y]
l = [B, 0, z]
l = [B, 1, w]
l = [B, 1, x]
l = [B, 1, y]
l = [B, 1, z]
l = [B, 2, w]
l = [B, 2, x]
l = [B, 2, y]
l = [B, 2, z]
Upvotes: 0
Reputation: 698
Use a for loop inside a for loop. The outer loop iterates through the array for the first element in each of your combinations, and the inner loop iterates through the other array.
Upvotes: 0