[英]How to get Cartesian product from Lists
Say I have several List<T>
s, I will put them into another list(or other collections), so I don't know how many list I have until I call List>.size() 假设我有几个
List<T>
,我会把它们放到另一个列表(或其他集合)中,所以我不知道有多少列表,直到我调用List> .size()
Take below List as an example: 以下面的列表为例:
list1=[1,2]
list2=[3,4]
list3=[5,6]
....
listn=[2*n-1,2n];
How can I get the result of list1*list2*list3*...listn as a Cartesian product 如何将list1 * list2 * list3 * ... listn的结果作为笛卡尔积
For example: 例如:
list1*list2*list3 should =[1,3,5],[1,3,6],[1,4,5],[1,4,6],[2,3,5],[2,3,6],[2,4,5],[2,4,6]
You can use recursion to achieve it, your base case of recursion is when input is empty then return empty list, else process the remaining elements. 您可以使用递归来实现它,递归的基本情况是当输入为空然后返回空列表,否则处理剩余的元素。 Eg
例如
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
public class CartesianProduct {
public static <T> List<List<T>> calculate(List<List<T>> input) {
List<List<T>> res = new ArrayList<>();
if (input.isEmpty()) { // if no more elements to process
res.add(new ArrayList<>()); // then add empty list and return
return res;
} else {
process(input, res); // we need to calculate the cartesian product of input and store it in res variable
}
return res; // method completes , return result
}
private static <T> void process(List<List<T>> lists, List<List<T>> res) {
List<T> head = lists.get(0); //take first element of the list
List<List<T>> tail = calculate(lists.subList(1, lists.size())); //invoke calculate on remaining element, here is recursion
for (T h : head) { // for each head
for (List<T> t : tail) { //iterate over the tail
List<T> tmp = new ArrayList<>(t.size());
tmp.add(h); // add the head
tmp.addAll(t); // and current tail element
res.add(tmp);
}
}
}
public static void main(String[] args) {
//we invoke the calculate method
System.out.println(calculate(Arrays.asList(Arrays.asList(1, 2), Arrays.asList(3, 4), Arrays.asList(5, 6))));
}
}
Output 产量
[[1, 3, 5], [1, 3, 6], [1, 4, 5], [1, 4, 6], [2, 3, 5], [2, 3, 6], [2, 4, 5], [2, 4, 6]]
Thanks to @sol4me 's answer using tail recursion, here is another version which is not using tail recursion but I think is easier to understand. 感谢@ sol4me使用尾递归的答案,这是另一个不使用尾递归的版本,但我认为更容易理解。
public class CartesianProduct {
public static <T> List<List<T>> calculate(List<List<T>> input) {
List<List<T>> result= new ArrayList<List<T>>();
if (input.isEmpty()) { // If input a empty list
result.add(new ArrayList<T>());// then add empty list and return
return result;
} else {
List<T> head = input.get(0);//get the first list as a head
List<List<T>> tail= calculate(input.subList(1, input.size()));//recursion to calculate a tail list
for (T h : head) {//we merge every head element with every tail list.
for (List<T> t : tail) {
List<T> resultElement = new ArrayList<T>();
resultElement.add(h);
resultElement.addAll(t);
result.add(resultElement);
}
}
}
return result;
}
public static void main(String[] args) {
List<List<Integer>> bigList=Arrays.asList(Arrays.asList(1,2),Arrays.asList(3,4),Arrays.asList(5,6),Arrays.asList(7,8));
System.out.println(calculate(bigList));
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.