【问题标题】:java generate powerset permutations from grouped elementsjava从分组元素生成powerset排列
【发布时间】:2015-08-13 05:40:38
【问题描述】:

我有一组 N 个组,每个组包含可变数量的元素。我想要一个函数,它将返回所有元素的所有可能排列(长度为 1 到 N),其中每组只有一个元素可以出现在任何排列中。

例如,考虑 2 个组 {A, B}{C, D, E}
然后我想返回以下列表:

{A}, {B}, {C}, {D}, {E},
{AC}, {AD}, {AE}, {BC}, {BD}, {BE}, {CA}, {CB}, {DA}, {DB}, {EA}, {EB}

我尝试编写一个递归函数,但我似乎无法让它工作......这是我目前所拥有的。任何帮助使其工作的帮助将不胜感激。

public class Test {
    public static void main(String[] args) {

        List<String> g1 = new ArrayList<String>();
        g1.add("a");
        g1.add("b");
        List<String> g2 = new ArrayList<String>();
        g2.add("c");
        g2.add("d");
        g2.add("e");
        List<List<String>> groups = new ArrayList<List<String>>();
        groups.add(g1);
        groups.add(g2);
        int size = 2;

        List<List<String>> perms = generatePermutations(groups, size);
        System.out.println(perms.size());

    }

    private static List<List<String>> generatePermutations(List<List<String>> groups, int size) {
        List<List<String>> permutations = new ArrayList<List<String>>();
        if ( groups.size() == 0 ) {
            return permutations;
        }
        int n = groups.size();
        for ( int i=0; i<n; i++ ) {
            List<List<String>> otherGroups = new ArrayList<List<String>>(groups);
            otherGroups.remove(i);
            for ( int j=0; j<groups.get(i).size(); j++ ) {
                String aKey = groups.get(i).get(j);
                for ( List<String> subPerm : generatePermutations(otherGroups, size - 1) ) {
                    List<String> newList = new ArrayList<String>();
                    newList.add(aKey);
                    newList.addAll(subPerm);
                    permutations.add(newList);
                }
            }
        }
        return permutations;
    }
}

【问题讨论】:

  • 你为什么不使用简单的数组,它不会让一切变得不那么冗长吗?

标签: java recursion permutation powerset


【解决方案1】:

当我必须解决此类问题时,我总是尝试将它们划分为较小的任务,每个任务都会导致不同的方法调用,而不是从一开始就使用许多内部循环。

我会做这样的事情

public class Main {

    public static void main(String[] args) {
        char[] x={'A','B'},y={'C','D','E'},z={'F','G','H','I'};
        char[][]group={x,y,z};
        perm(group);
    }

    static void perm(char[][]g){
        // Reorganize "g" changing the order of the components (x, y and z in this case)
        // in all possible ways and call perm2().
        // Here you perform the "upper level" permutation between sets.
        // In this case it will result in 6 calls
            perm2(g);
    }

    static void perm2(char[][]g){
        // perform a "lower level" permutation on the given order of x, y, z
    }

}

这更容易测试和验证。最终,当您找到解决方案时,您可以考虑用一种方法“压缩”解决方案,其中包含多个内部循环。

希望对你有帮助!

【讨论】:

    【解决方案2】:

    也许我误解了这个问题......但我认为这个问题有点令人费解。我想帮忙,但我需要更好地理解这个问题。如果我理解正确,您需要:

    找到作为输入给出的“集合集”的幂集:

    {A,B} {C,D,E} --> {} {A,B} {C,D,E} {{A,B},{C,D,E}}
    

    然后,计算幂集每个成员的笛卡尔积:

    {} {A,B} {C,D,E} {{A,B},{C,D,E}} --> {} {A,B} {C,D,E} {AC,AD,AE,BC,BD,BE}
    

    然后计算得到的集合内容的排列:

    {} {A,B} {C,D,E} {AC,AD,AE,BC,BD,BE} --> {} {A,B} {C,D,E} {AC,AD,AE,BC,BD,BE,CA,DA,EA,CB,DB,EB}
    

    最后,所有集合都将被“展平”在一个集合中:

    {A,B,C,D,EAC,AD,AE,BC,BD,BE,CA,DA,EA,CB,DB,EB}
    

    是这样吗?有多种方法可以递归计算幂集、笛卡尔积和排列。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-06
      • 2019-07-18
      • 2011-12-31
      • 1970-01-01
      • 1970-01-01
      • 2013-04-14
      • 1970-01-01
      • 2011-05-14
      相关资源
      最近更新 更多