Java 获取列表组合的列表';元素

Java 获取列表组合的列表';元素,java,combinatorics,Java,Combinatorics,假设我有3个列表:['q','w'],['a','s'],['z','x']。如何从这些列表中获得可能的组合列表?所以我得到一个列表['q','a','z',['q','s','z']]等等。我为两个列表创建了一个方法,但无法为N个列表创建一个: static <E> ArrayList combine(ArrayList<E> one,ArrayList<E> two) { ArrayList<ArrayList<E>> co

假设我有3个列表:['q','w'],['a','s'],['z','x']。如何从这些列表中获得可能的组合列表?所以我得到一个列表['q','a','z',['q','s','z']]等等。我为两个列表创建了一个方法,但无法为N个列表创建一个:

static <E> ArrayList combine(ArrayList<E> one,ArrayList<E> two)
{
    ArrayList<ArrayList<E>> combs=new ArrayList<ArrayList<E>>();
    for(E e:one)
    {
        for(E e2:two)
        {
            ArrayList ps=new ArrayList();
            ps.add(e);
            ps.add(e2);
            combs.add(ps);
        }
    }
    return combs;
}
静态ArrayList组合(ArrayList 1,ArrayList 2)
{
ArrayList combs=新的ArrayList();
(E:1)
{
(E)e2:2
{
ArrayList ps=新的ArrayList();
ps.add(e);
ps.add(e2);
梳子。添加(ps);
}
}
回梳;
}

我发现这是由Guava的Sets.cartesianProduct完成的。

您需要N个嵌套循环,这使得它很难实现

不过,您可以使用递归实现这一点

static <E> ArrayList combine(ArrayList<E> soFar, ArrayList<E>... lists)
{
    // Rather than constantly making and remaking this list could just use one
    // and pass it around and add stuff to it. This works though.
    ArrayList<ArrayList<E>> combs=new ArrayList<ArrayList<E>>();

    // Loop through the first list looking for elements
    for(E e:lists[0])
    {
       // Create a new List to build this combination
       ArrayList<E> temp = new ArrayList<>(soFar);
       // Add this element to the combination
       temp.add(e);
       // If there are more lists recurse down
       if (lists.length > 1) {
           // Use recursion to add all combinations of the remaining lists
           combs.addAll(combine(temp, lists.subList(1)));
       } else {
           // There are no more lists so we are done, add temp to the combos
           combs.add(temp);
       }
    }
    return combs;
}


// Call this method to start things going, the other one should probably be private
static <E> ArrayList combine(ArrayList<E>... lists)
    return combine(new ArrayList<E>(), lists);
}
静态ArrayList组合(ArrayList soFar、ArrayList…列表)
{
//与其不断地制作和重新制作这个列表,不如只使用一个
//然后把它传给别人,然后加上一些东西。不过这很有效。
ArrayList combs=新的ArrayList();
//在第一个列表中循环查找元素
对于(E:列表[0])
{
//创建新列表以构建此组合
ArrayList temp=新ArrayList(soFar);
//将此元素添加到组合中
临时添加(e);
//如果有更多列表,则会向下递归
如果(lists.length>1){
//使用递归添加剩余列表的所有组合
合并(临时列表、列表子列表(1));
}否则{
//没有更多的列表,所以我们完成了,将临时添加到组合中
梳齿添加(温度);
}
}
回梳;
}
//调用此方法开始工作,另一个可能是私有的
静态ArrayList组合(ArrayList…列表)
返回联合收割机(新ArrayList(),列表);
}

向上,您可以使用构造函数(参数…)创建一个内部类,这样您就可以放置一个此类列表,该列表处理所有组合

您可能希望查看该类(一个“独立”类,只需复制并插入到您的项目中)

用法示例:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Combinations
{
    public static void main(String[] args)
    {
        List<List<Character>> lists = new ArrayList<List<Character>>();
        lists.add(Arrays.asList('q','w'));
        lists.add(Arrays.asList('a','s'));
        lists.add(Arrays.asList('z','x'));

        MixedRangeCombinationIterable<Character> iterable = 
            new MixedRangeCombinationIterable<Character>(lists);
        for (List<Character> element : iterable)
        {
            System.out.println(element);
        }
    }
}
import java.util.ArrayList;
导入java.util.array;
导入java.util.List;
公共类组合
{
公共静态void main(字符串[]args)
{
List lists=新建ArrayList();
添加(Arrays.asList('q','w');
添加(Arrays.asList('a','s');
添加(Arrays.asList('z','x'));
MixedRangeCombinationIterable iterable=
新的MixedRangeCombinationIterable(列表);
for(列表元素:iterable)
{
系统输出打印项次(元素);
}
}
}
实际上,您正在为懒惰者(使用番石榴)计算输入集的元素:

Set result=Sets.cartesianProduct(
不可变集(“q”、“w”),
不可变集(“a”、“s”),
不可变集(“z”、“x”)
);
系统输出打印项次(结果);
输出:

[
[q,a,z],
[q,a,x],
[q,s,z],
[q,s,x],
[w,a,z],
[w,a,x],
[w,s,z],
[w,s,x]

]

如何调用lists.subList?这不是一个数组吗?很好,这里的所有代码都是直接键入的,因此需要进行一些调整。:)使用或只传递整个数组,并使用soFar.size()作为数组的索引。(第二种方法将更有效)。
Set<List<String>> result = Sets.cartesianProduct(
                ImmutableSet.of("q", "w"),
                ImmutableSet.of("a", "s"),
                ImmutableSet.of("z", "x")
        );

System.out.println(result);