Java 数组的所有可能组合

Java 数组的所有可能组合,java,arrays,algorithm,Java,Arrays,Algorithm,我有一个字符串数组 {"ted", "williams", "golden", "voice", "radio"} 我希望这些关键字的所有可能组合形式如下: {"ted", "williams", "golden", "voice", "radio", "ted williams", "ted golden", "ted voice", "ted radio", "williams golden", "williams voice", "williams r

我有一个字符串数组

{"ted", "williams", "golden", "voice", "radio"}
我希望这些关键字的所有可能组合形式如下:

{"ted",
 "williams",
 "golden", 
 "voice", 
 "radio",
 "ted williams", 
 "ted golden", 
 "ted voice", 
 "ted radio", 
 "williams golden",
 "williams voice", 
 "williams radio", 
 "golden voice", 
 "golden radio", 
 "voice radio",
 "ted williams golden", 
 "ted williams voice", 
 "ted williams radio", 
 .... }
我已经走了几个小时,没有任何有效的结果(高级编程的副作用??)

我知道解决办法应该是显而易见的,但老实说,我被卡住了!Java/C中的解决方案是可以接受的

编辑

  • 这不是家庭作业
  • “ted williams”和“williams ted”被认为是相同的,所以我只想要“ted williams”
  • 编辑2:查看答案中的链接后,发现Guava用户可以在com.google.common.collect.Sets中使用powerset方法

    All-Subsets(X) = {union for all y in X: All-Subsets(X-y)} union {X}
    

    编辑:正如FearUs指出的,更好的解决方案是使用番石榴汁

    编辑2:更新链接


    快速而肮脏地翻译:


    我刚刚遇到了这个问题,对StackExchange发布的答案不太满意,下面是我的答案。这将返回
    端口
    对象数组中的所有组合。我将把它留给读者来适应您使用的任何类(或使其成为通用类)

    此版本不使用递归

    public static Port[][] combinations ( Port[] ports ) {
        
        List<Port[]> combinationList = new ArrayList<Port[]>();
        // Start i at 1, so that we do not include the empty set in the results
        for ( long i = 1; i < Math.pow(2, ports.length); i++ ) {
            List<Port> portList = new ArrayList<Port>();
            for ( int j = 0; j < ports.length; j++ ) {
                if ( (i & (long) Math.pow(2, j)) > 0 ) {
                    // Include j in set
                    portList.add(ports[j]);
                }
            }
            combinationList.add(portList.toArray(new Port[0]));
        }
        return combinationList.toArray(new Port[0][0]);
    }
    
    公共静态端口[][]组合(端口[]端口){
    List combinationList=新建ArrayList();
    //从1开始,这样我们就不会在结果中包含空集
    for(long i=1;i0){
    //在集合中包含j
    portList.add(端口[j]);
    }
    }
    添加(portList.toArray(新端口[0]);
    }
    返回combinationList.toArray(新端口[0][0]);
    }
    
    有关更优化的版本,请参阅本页@Aison提供的解决方案。

    包rnd;
    
    package rnd;
    
    import java.util.ArrayList;
    
    public class Rnd {
        public static void main(String args[]) {
            String a[] = {"ted", "williams", "golden", "voice", "radio"};
            ArrayList<String> result =new ArrayList<>();
            for(int i =0 ;i< a.length; i++){
                String s = "";
                for(int j =i ; j < a.length; j++){
                    s += a[j] + " " ;
                    result.add(s);
                }
            }
        }
    }
    
    导入java.util.ArrayList; 公共类Rnd{ 公共静态void main(字符串参数[]){ 字符串a[]={“ted”、“williams”、“golden”、“voice”、“radio”}; ArrayList结果=新建ArrayList(); for(int i=0;i
    我知道这个问题很老,但我没有找到一个能满足我需要的答案。因此,使用幂集的思想,以及番石榴库的有序排列,我能够获得原始数组中所有元素组合的数组

    我想要的是:

    如果我有一个包含三个字符串的数组

    ArrayList<String> tagsArray = new ArrayList<>(Array.asList("foo","bar","cas"));
    
    为了得到这个结果,我使用google的guava库实现了下一个代码:

      import static com.google.common.collect.Collections2.orderedPermutations;
      import static java.util.Arrays.asList;
    
      public void createTags(){
    
        Set<String> tags =  new HashSet<>();
        tags.addAll(tagsArray);
        Set<Set<String>> tagsSets = Sets.powerSet(tags);
    
        for (Set<String> sets : tagsSets) {
            List<String> myList = new ArrayList<>();
            myList.addAll(sets);
            if (!myList.isEmpty()) {
                for (List<String> perm : orderedPermutations(myList)) {
                    System.out.println(perm);
                    String myTag = Joiner.on("").join(perm);
                    tagsForQuery.add(myTag);
                }
            }
        }
    
        for (String hashtag : tagsForQuery) {
            System.out.println(hashtag);
        }
    }
    
    导入静态com.google.common.collect.Collections2.orderedPermutations;
    导入静态java.util.Arrays.asList;
    公共void createTags(){
    Set tags=newhashset();
    tags.addAll(tagsArray);
    Set tagsSets=Set.powerSet(标签);
    用于(集合:标记集合){
    List myList=new ArrayList();
    myList.addAll(集合);
    如果(!myList.isEmpty()){
    for(列表置换:有序置换(myList)){
    系统输出打印项次(perm);
    字符串myTag=Joiner.on(“”).join(perm);
    tagsForQuery.add(myTag);
    }
    }
    }
    for(字符串hashtag:tagsForQuery){
    System.out.println(hashtag);
    }
    }
    

    我希望这能帮助一些人,这不是家庭作业,而是android应用。

    我的优化解决方案基于Matthew McPeak提供的解决方案。此版本避免了不必要的阵列副本

    public static <T> T[][] combinations(T[] a) {
    
        int len = a.length;
        if (len > 31)
            throw new IllegalArgumentException();
    
        int numCombinations = (1 << len) - 1;
    
        @SuppressWarnings("unchecked")
        T[][] combinations = (T[][]) java.lang.reflect.Array.newInstance(a.getClass(), numCombinations);
    
        // Start i at 1, so that we do not include the empty set in the results
        for (int i = 1; i <= numCombinations; i++) {
    
            @SuppressWarnings("unchecked")
            T[] combination = (T[]) java.lang.reflect.Array.newInstance(a.getClass().getComponentType(),
                    Integer.bitCount(i));
    
            for (int j = 0, ofs = 0; j < len; j++)
                if ((i & (1 << j)) > 0)
                    combination[ofs++] = a[j];
    
            combinations[i - 1] = combination;
        }
    
        return combinations;
    }
    
    公共静态T[]a组合(T[]a){
    int len=a.长度;
    如果(len>31)
    抛出新的IllegalArgumentException();
    int numCombinations=(1
    import java.util.ArrayList;
    导入java.util.List;
    公共类所有可能的组合{
    公共静态void main(字符串[]args){
    字符串[]a={“ted”、“williams”、“golden”};
    List List=new AllPossibleElementCombinations().getAllCombinations(Arrays.asList(a));
    对于(列表arr:List){
    用于(字符串s:arr){
    系统输出打印;
    }
    System.out.println();
    }
    }
    公共列表GetAllCombinitions(列表元素){
    List combinationList=新建ArrayList();
    for(长i=1;i0){
    list.add(elements.get(j));
    }
    }
    组合列表。添加(列表);
    }
    返回组合列表;
    }
    }
    
    输出:

    特德

    威廉姆斯

    特德威廉姆斯

    金色的

    泰德黄金

    威廉斯戈登


    TED WilliamsGolden

    是的,谢谢,这正是我需要的,经过测试,工作完美:)谢谢你的代码片段。节省了我的时间!!断开了到原始源代码的链接。断开了到guava doc的链接。还请注意,生成的数组的输入大小将是指数级的,这意味着您生成的数组很容易只需要30个输入字就可以占用数GB的空间,因此如果您需要更大的输入数组,请避免使用这种方法。看起来这是answ在StackOverflow中搜索
    数组组合
    会得到“5000+”结果(167页),第一页上的许多结果都是这个完全相同的问题,其中大多数被标记为
    家庭作业
    不,这不是家庭作业,我有一个注释列表,想利用包含这些组合的顶级网页。我不想寻找2个阵列的笛卡尔积。不幸的是,这种方法没有得到所有组合。例如,它不会产生组合“ted收音机”。谢谢。请您对我的回答发表意见,指出不必要的阵列副本在哪里?遗憾的是,我不能直接评论您的回答,因为我的声誉仍然太低。但您
    {"foo","bar","cas","foobar","foocas","barfoo","barcas","casfoo","casbar","foobarcas","casbarfoo","barcasfoo" . . . . . }
    
      import static com.google.common.collect.Collections2.orderedPermutations;
      import static java.util.Arrays.asList;
    
      public void createTags(){
    
        Set<String> tags =  new HashSet<>();
        tags.addAll(tagsArray);
        Set<Set<String>> tagsSets = Sets.powerSet(tags);
    
        for (Set<String> sets : tagsSets) {
            List<String> myList = new ArrayList<>();
            myList.addAll(sets);
            if (!myList.isEmpty()) {
                for (List<String> perm : orderedPermutations(myList)) {
                    System.out.println(perm);
                    String myTag = Joiner.on("").join(perm);
                    tagsForQuery.add(myTag);
                }
            }
        }
    
        for (String hashtag : tagsForQuery) {
            System.out.println(hashtag);
        }
    }
    
    public static <T> T[][] combinations(T[] a) {
    
        int len = a.length;
        if (len > 31)
            throw new IllegalArgumentException();
    
        int numCombinations = (1 << len) - 1;
    
        @SuppressWarnings("unchecked")
        T[][] combinations = (T[][]) java.lang.reflect.Array.newInstance(a.getClass(), numCombinations);
    
        // Start i at 1, so that we do not include the empty set in the results
        for (int i = 1; i <= numCombinations; i++) {
    
            @SuppressWarnings("unchecked")
            T[] combination = (T[]) java.lang.reflect.Array.newInstance(a.getClass().getComponentType(),
                    Integer.bitCount(i));
    
            for (int j = 0, ofs = 0; j < len; j++)
                if ((i & (1 << j)) > 0)
                    combination[ofs++] = a[j];
    
            combinations[i - 1] = combination;
        }
    
        return combinations;
    }
    
    import java.util.ArrayList;
    import java.util.List;
    public class AllPossibleCombinations {
    
    public static void main(String[] args) {
        String[] a={"ted", "williams", "golden"};           
        List<List<String>> list = new AllPossibleElementCombinations().getAllCombinations(Arrays.asList(a));
        for (List<String> arr:list) {
            for(String s:arr){
                System.out.print(s);
            }
            System.out.println();
        }
    }
    
    public List<List<String>> getAllCombinations(List<String> elements) {
        List<List<String>> combinationList = new ArrayList<List<String>>();
        for ( long i = 1; i < Math.pow(2, elements.size()); i++ ) {
            List<String> list = new ArrayList<String>();
            for ( int j = 0; j < elements.size(); j++ ) {
                if ( (i & (long) Math.pow(2, j)) > 0 ) {
                    list.add(elements.get(j));
                }
            }
            combinationList.add(list);
        }
        return combinationList;
    }
    
    }