生成所有可能的组合 - Java [重复]

Posted

技术标签:

【中文标题】生成所有可能的组合 - Java [重复]【英文标题】:Generate All Possible Combinations - Java [duplicate] 【发布时间】:2016-10-16 13:26:06 【问题描述】:

我有一个项目列表 a,b,c,d,我需要生成所有可能的组合,

您可以选择任意数量的项目 顺序不重要 (ab = ba) 不考虑空集

如果我们考虑可能性,它应该是,

n=4, number of items
total #of combinations = 4C4 + 4C3 + 4C2 + 4C1 = 15

我使用了以下递归方法:

private void countAllCombinations (String input,int idx, String[] options) 
    for(int i = idx ; i < options.length; i++) 
        String output = input + "_" + options[i];
        System.out.println(output);
        countAllCombinations(output,++idx, options);
    


public static void main(String[] args) 
    String arr[] = "A","B","C","D";
    for (int i=0;i<arr.length;i++) 
        countAllCombinations(arr[i], i, arr);
    

当数组很大时,有没有更有效的方法?

【问题讨论】:

这是一个指数算法,所以对于 large 数组,无论如何它仍然会很慢。 你可以看看***.com/questions/20935315/…和***.com/questions/15498281/… 是的,还有更有效的方法。有现成的解决方案(这里在堆栈上)用于从大小为 N 的列表中生成大小为 M 的子集以及用于子集的排列。他们的组合会做你想要的。 在您的情况下,组合的数量在 java Math.pow(2,n)-1 中,其中 n 是您的数组的大小 链接的“重复”是一个更复杂、不同的问题 【参考方案1】:

将组合视为二进制序列,如果所有 4 个都存在,我们得到 1111,如果第一个字母缺失,那么我们得到 0111,依此类推。所以对于 n 个字母,我们将有 2^n -1 (因为不包括 0)组合。

现在,在您生成的二进制序列中,如果代码为 1 ,则该元素存在,否则不包括在内。以下是概念验证实现:

String arr[] =  "A", "B", "C", "D" ;
int n = arr.length;
int N = (int) Math.pow(2d, Double.valueOf(n));  
for (int i = 1; i < N; i++) 
    String code = Integer.toBinaryString(N | i).substring(1);
    for (int j = 0; j < n; j++) 
        if (code.charAt(j) == '1') 
            System.out.print(arr[j]);
        
    
    System.out.println();

这是一个通用的可重用实现:

public static <T> Stream<List<T>> combinations(T[] arr) 
    final long N = (long) Math.pow(2, arr.length);
    return StreamSupport.stream(new AbstractSpliterator<List<T>>(N, Spliterator.SIZED) 
        long i = 1;
        @Override
        public boolean tryAdvance(Consumer<? super List<T>> action) 
            if(i < N) 
                List<T> out = new ArrayList<T>(Long.bitCount(i));
                for (int bit = 0; bit < arr.length; bit++) 
                    if((i & (1<<bit)) != 0) 
                        out.add(arr[bit]);
                    
                
                action.accept(out);
                ++i;
                return true;
            
            else 
                return false;
            
        
    , false);

【讨论】:

以上是关于生成所有可能的组合 - Java [重复]的主要内容,如果未能解决你的问题,请参考以下文章

生成 0, 1,...n-1, n 个 k 数的所有可能组合。每个组合应按升序排列[重复]

为X位数生成0-9的所有唯一组合[重复]

用java找出这几个list,所有可能的组合,并且组合结果的list中的数据不允许重复

两个数组的递归组合项(不为空或重复),使用 Java

Java - 当变量等于字符串时,如果语句没有捕获[重复]

R从n个元素的字符向量中生成大小为m的所有可能组合[重复]