【发布时间】:2018-05-15 10:27:43
【问题描述】:
假设我有一个包含 n 个字符串列表的列表:
例如当 n = 3 时
list1 = ["M","G"];
list2 = ["VP","P"];
list3 = ["E"]
输出必须是所有可能组合的列表,每个组合必须包含每个列表中的一个元素。
上面同一个例子的输出一定是:
2*2*1 = 4 个组合,每个组合必须准确包含 3 个字符串(每个输入列表中的一个)。
lists= [ ["M","VP","E"], ["M","P","E"], ["G","VP","E"], ["G","P","E"] ]
我尝试了一个递归函数,但我注意到下面的当前列表在递归期间无法保留旧版本:
lists -> 包含所有输入列表(例如,list1、list2 和 list3)
result -> 包含所有输出列表(所有组合)
current -> 是当前的组合
public static void combination(ArrayList<ArrayList<String>> lists, ArrayList<ArrayList<String>> result, ArrayList<String> current, int k){
if(k==lists.size()){
result.add(current);
current = new ArrayList<String>();
System.out.println("(if) || k="+k+" || current"+current);
return;
}
for(int t=0;t<lists.get(k).size();t++){
current.add(lists.get(k).get(t));
System.out.println("(for) || k="+k+" || current"+current);
combination(lists, result, current, k+1);
}
}
使用上述相同示例调用此函数时的输出:
public static void main(String[] args){
ArrayList<String> l1 = new ArrayList<String>();l1.add("M");l1.add("G");
ArrayList<String> l2 = new ArrayList<String>();l2.add("VP");l2.add("P");
ArrayList<String> l3 = new ArrayList<String>();l3.add("E");
ArrayList<ArrayList<String>> lists = new ArrayList<ArrayList<String>>();
ArrayList<ArrayList<String>> result = new ArrayList<ArrayList<String>>();
ArrayList<String> current = new ArrayList<String>();
lists.add(l1);lists.add(l2);lists.add(l3);
combination(lists, result, current, 0);
for(int i=0;i<result.size();i++){
System.out.println(result.get(i));
}
}
输出是:
(for) || k=0 || current[M]
(for) || k=1 || current[M, VP]
(for) || k=2 || current[M, VP, E]
(if) || k=3 || current[]
(for) || k=1 || current[M, VP, E, P]
(for) || k=2 || current[M, VP, E, P, E]
(if) || k=3 || current[]
(for) || k=0 || current[M, VP, E, P, E, G]
(for) || k=1 || current[M, VP, E, P, E, G, VP]
(for) || k=2 || current[M, VP, E, P, E, G, VP, E]
(if) || k=3 || current[]
(for) || k=1 || current[M, VP, E, P, E, G, VP, E, P]
(for) || k=2 || current[M, VP, E, P, E, G, VP, E, P, E]
(if) || k=3 || current[]
[M, VP, E, P, E, G, VP, E, P, E]
[M, VP, E, P, E, G, VP, E, P, E]
[M, VP, E, P, E, G, VP, E, P, E]
[M, VP, E, P, E, G, VP, E, P, E]
例如:
这一行:(for) || k=1 || current[M, VP, E, P]
必须是:(for) || k=1 || current[M, VP]
但 current 不会将其旧版本保留在调用它的递归函数中。
【问题讨论】:
-
您没有处理 Java 始终为 pass-by-value 的事实。当您执行
current = new ArrayList<String>();时,您不会修改先前递归调用的current列表,而只是修改方法内“当前”列表的值。
标签: java list recursion combinations