找出所有组合和排列 - Java

时间:2013-06-16 14:09:01

标签: java combinations permutation

我是新来的,也是初学者。我正在开发一个个人项目(开发一个供个人使用的应用程序)。我有点卡住了,是的,我确实搜索过,但找不到多少。 我的目标是找到所有可能的组合。假设我有一些有限数量的列表定义如下:

List<String> AList contains {"a1","a2","a3","a4"} 
List<String> BList contains {"b1","b2","b3"} 
List<String> CList contains {"c1","c2","c3","c4","c5"} 
List<String> DList contains {"d1","d2"}

我想找到所有组合:

1)组合a1 a2静脉与a2 a1相同,依此类推

2)每个结果集的元素数量没有被修复:组合可能性是每个例子将所有列表合并为一个..或者自己列表中的每个元素,或者合并列表中的两个元素,其余元素合并到另一个元素中..等等..

我知道它必须是一个递归函数..但是我现在有多远...任何帮助将不胜感激。谢谢

2 个答案:

答案 0 :(得分:1)

这是我之前为此目的实现的实用程序类。它使用int数组而不是String列表,但它应该会给你一个想法:

public final class Math {

    private Math() {
    }

    public static int[][] ncks(int n, int k) {
        int[] ks = new int[k];
        for (int i = 0; i < ks.length; i++) {
            ks[i] = i + 1;
        }

        int[][] ncks = new int[nck(n, k)][];

        boolean done = false;
        for (int j = 0; !done; j++) {
            ncks[j] = Arrays.copyOf(ks, ks.length);
            done = getNext(ks, n, k);
        }
        return ncks;
    }

    private static int nck(int n, int k) {
        int d = 1;
        int r = 1;

        int m = java.lang.Math.max(k, n - k) + 1;
        for (; m <= n; m++, d++) {
            r *= m;
            r /= d;
        }
        return r;
    }

    private static boolean getNext(int[] num, int n, int k) {
        int target = k - 1;

        num[target]++;
        if (num[target] > ((n - (k - target)) + 1)) {
            while (num[target] > ((n - (k - target)))) {
                target--;
                if (target < 0) {
                    break;
                }
            }

            if (target < 0) {
                return true;
            }

            num[target]++;
            for (int i = target + 1; i < num.length; i++) {
                num[i] = num[i - 1] + 1;
            }
        }
        return false;
    }

}

答案 1 :(得分:0)

我为自己做了类似的事情,然而这会给你a1 a2等的排列而不是组合,这意味着顺序并不重要。

public void permutation(String prefix, String str) {
    int n = str.length();
    if (n==0){}
    else {
        for (int i = 0; i < n; i++)
            permutation(prefix + str.charAt(i), str.substring(0, i) + str.substring(i+1, n));
    }

}

使用此逻辑,您必须将列表转换为一个长字符串,然后将此方法发送到您的字符串