package org.archive.util;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
import java.util.Stack;
public class CrossProduct <T> {
public List<List<T>> crossProduct(List<List<T>> listOfLists) {
ArrayList<List<T>> results = new ArrayList<List<T>>();
Stack<T> current = new Stack<T>();
Deque<List<T>> remainder = new ArrayDeque<List<T>>(listOfLists);
recurse(remainder,current,results);
return results;
}
private void recurse(Deque<List<T>> remainder,
Stack<T> current, ArrayList<List<T>> accumulation) {
if(remainder.isEmpty()) {
// all done:
dump(new ArrayList<T>(current));
accumulation.add(new ArrayList<T>(current));
} else {
List<T> cur = remainder.removeFirst();
for(T o : cur) {
current.push(o);
recurse(remainder,current,accumulation);
current.pop();
}
remainder.addFirst(cur);
}
}
private void dump(ArrayList<T> a) {
StringBuilder sb = new StringBuilder();
boolean first = false;
for(T o : a) {
if(first) {
first = false;
} else {
sb.append(",");
}
sb.append(o.toString());
}
System.out.println("CrossOutput:" + sb.toString());
}
}