获取List的Powerset的最佳方式(递归)

时间:2013-07-26 21:44:54

标签: java combinations set powerset

为了获得列表的功能集,我实现了以下内容:

public static ArrayList<ArrayList<Integer>> getAllSubsets(ArrayList<Integer> set, int index, ArrayList<Integer> subset){
    ArrayList<ArrayList<Integer>> subsets = new ArrayList<ArrayList<Integer>>();

    if(index == set.size()){
        subsets.add(new ArrayList<Integer>(subset));
        return subsets;
    }

    subsets.addAll(getAllSubsets(set, index + 1, subset));
    subset.add(set.get(index));
    subsets.addAll(getAllSubsets(set, index + 1, subset));
    subset.remove(subset.size()-1);
    return subsets;
}

这是使用递归获取列表的幂集的最佳方法吗?我已经看到了很多关于如何在互联网上实现这一点的不同方法,但它们似乎比我的更多地复制(使用新的)。

例如,这个StackOverlow post出现在我的谷歌搜索中,但他的实现(Joao Silva)使用了大量复制并且似乎不是最佳的。但是,我经常看到他的实施让我感到困惑。这个实现是否比我正在使用的更好(其他当然他使用泛型的事实)?

他的代码:

public static <T> Set<Set<T>> powerSet(Set<T> originalSet) {
    Set<Set<T>> sets = new HashSet<Set<T>>();
    if (originalSet.isEmpty()) {
        sets.add(new HashSet<T>());
        return sets;
    }
    List<T> list = new ArrayList<T>(originalSet);
    T head = list.get(0);
    Set<T> rest = new HashSet<T>(list.subList(1, list.size())); 
    for (Set<T> set : powerSet(rest)) {
        Set<T> newSet = new HashSet<T>();
        newSet.add(head);
        newSet.addAll(set);
        sets.add(newSet);
        sets.add(set);
    }       
    return sets;
}

1 个答案:

答案 0 :(得分:2)

您可能会发现此page有用。它包含各种语言的powerset实现,并使用不同的方法。对于Java,有三种方法:

  1. 迭代
  2. 递归
  3. 并使用二进制字符串
  4. 其实我最喜欢第三种方式,因为那里有好主意。不同之处在于,他们假设输入为String

    顺便说一句。如果它将是将在生产中使用的任何代码,我宁愿避免使用递归,因为堆栈可能存在问题(遗憾的是,Java中仍然不支持尾递归)