当前位置: 首页 > 面试题库 >

生成所有可能的组合-Java

沃学
2023-03-14
问题内容

我有一个项目{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);
    }
}

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


问题答案:

将组合视为一个二进制序列,如果所有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);
}


 类似资料:
  • 问题内容: 目前,我试图让所有可能的组合从的,是每一个元素只包含一个字母。 在本身包含相同字母两次甚至更多,他们只应该,因为他们经常会出现使用。 在稍后应该含有最多的给定的长度从最小的2个字母的所有组合。 我在此处搜索了stackoverflow,但只发现了忽略以下事实的置换函数:每个字母仅在出现时才经常使用。 这是我的第一个Swift 2项目,所以请原谅我的绿色态度:) 我想要的是 我目前的做法

  • 问题内容: 似乎比它要简单得多,但是如何用python生成所有16,777,255个rgb颜色呢? 问题答案: 颜色通常用十六进制数表示,实际上只是整数。因此,从0到16,777,215(0xFFFFFF)的简单循环就足以生成所有24位RGB颜色。 在python 2.x中,您可以执行以下操作:

  • 我有下表: 对于两组中的每一组,我想返回所有可能的值组合。对于组1,例如,可能的组合是(A, B)、(A, C)、(A, D)、(B, C)、(B, D)、(C, D)、(A, B, C)、(B, D, C)、(C, A, B)。类似地,对于组2,它是(A, B)、(A, C)、(B, C)[备注:我不想考虑(1)只有一个值的组合,(2)所有值的组合和(3)没有值的组合。因此,对于n个不同的值,我

  • 我有亲戚 并想在PostgreSQL中加入它 所以我得到了所有可能的替换组合(即替换或多或少的笛卡尔积)。所以组1没有更新,组2只有B2,组3只有D2,组4都有B2和D2。 结尾应该是这样的,但应该对更多人开放(就像D1的额外D3) 编辑: 另一个可能的替换表可以是 可能会导致6组(我希望我没有忘记一个案例) 如果你有三个替代品,比如 这将导致8组。到目前为止,我所尝试的并没有真正的帮助: 我很高