假设我有一个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"] ]
我尝试了一个递归函数,但我注意到下面的当前列表在递归过程中不能保留旧版本:
列表 - >包含所有输入列表(例如,list1,list2和list3)
结果 - >包含所有输出列表(所有组合)
当前 - >是目前的组合
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]
但是当前并没有将旧版本保留在调用它的递归函数中。
答案 0 :(得分:0)
另一种方法,可能更容易:
public static List<List<String>> combination(List<List<String>> lists){
if (lists.size() == 1) {
return lists;
} else {
List<List<String>> subcombs = combination(lists.subList(1, lists.size()));
List<List<String>> result = new ArrayList<>();
for (String s : lists.get(0)) {
for (List<String> subcomb : subcombs) {
List<String> list = new ArrayList<>();
list.add(s);
list.addAll(subcomb);
result.add(list);
}
}
return result;
}
}
public static void main(String[] args){
List<String> l1 = Arrays.asList("M", "G");
List<String> l2 = Arrays.asList("VP", "P");
List<String> l3 = Arrays.asList("E");
System.out.println(combination(Arrays.asList(l1, l2, l3)));
// Output: [[M, VP, E], [M, P, E], [G, VP, E], [G, P, E]]
}
在每个递归步骤中,只需计算子组合并在前面添加当前列表的每个字符串
答案 1 :(得分:0)
我认为这两种方法可以完成这项工作:
public static void main(String[] args) {
List<String> list1 = Arrays.asList("M,G".split(","));
List<String> list2 = Arrays.asList("VP,P".split(","));
List<String> list3 = Arrays.asList("E".split(""));
List<List<String>> mainList = new ArrayList<>();
mainList.add(list1);
mainList.add(list2);
mainList.add(list3);
combination(mainList, new ArrayList<>());
}
public static void combination(List<List<String>> remainingListsToUse, ArrayList<String> current)
{
if(remainingListsToUse.isEmpty())
{
System.out.println(current.toString());
return;
}
for(List<String> remainingListToUse : remainingListsToUse)
{
List<List<String>> listsToKeepGoingWith = new ArrayList<>();
listsToKeepGoingWith.addAll(remainingListsToUse);
listsToKeepGoingWith.remove(remainingListToUse);
remainingListToUse.forEach(listUsed->{
ArrayList<String> newCurrent = new ArrayList<>();
newCurrent.addAll(current);
newCurrent.add(listUsed);
combination(listsToKeepGoingWith, newCurrent);
});
}
}
我认为可以排列不同的列表......
结果如下:
[M, VP, E]
[M, P, E]
[M, E, VP]
[M, E, P]
[G, VP, E]
[G, P, E]
[G, E, VP]
[G, E, P]
[VP, M, E]
[VP, G, E]
[VP, E, M]
[VP, E, G]
[P, M, E]
[P, G, E]
[P, E, M]
[P, E, G]
[E, M, VP]
[E, M, P]
[E, G, VP]
[E, G, P]
[E, VP, M]
[E, VP, G]
[E, P, M]
[E, P, G]
希望它会对你有所帮助! :)
编辑:
如果订单和unicity maters你可能更喜欢这种方法:
public static void combination(List<List<String>> remainingListsToUse, ArrayList<String> current)
{
// If all the lists have been used
if(remainingListsToUse.isEmpty())
{
System.out.println(current.toString());
return;
}
if(!remainingListsToUse.isEmpty())
{
List<String> listCurrentlyUsed = remainingListsToUse.get(0);
List<List<String>> newRemainingListToUse = new ArrayList<>();
newRemainingListToUse.addAll(remainingListsToUse);
newRemainingListToUse.remove(listCurrentlyUsed);
listCurrentlyUsed.forEach(listElementUsed->{
ArrayList<String> newCurrent = new ArrayList<>();
newCurrent.addAll(current);
newCurrent.add(listElementUsed);
combination(newRemainingListToUse, newCurrent);
});
}
}
结果就是这样:
[M, VP, E]
[M, P, E]
[G, VP, E]
[G, P, E]