使用递归获取具有特定参数的集合的所有组合

时间:2017-03-03 14:25:09

标签: java recursion

我想找到一种方法来使用递归来生成具有一些参数的集合中所有元素的独特组合... 1)我希望能够定义单个组合的大小。 2)我希望能够从集合中提供我自己的元素(少于提供的大小)来生成包含我提供的元素的所有组合。

由于可能令人困惑,输入看起来像这样......

输入:(元素集,单个组合的大小,提供的元素(从0到大小-1)

输出:所有可能组合的集合(顺序无关紧要)

例如,假设我将字母a-z作为我提供的元素集合。让我们也说我希望组合的大小为5.我们也说我为方法提供了“FG”。

getCombos(Set<V> collection, int size, Set<V> provided)

return Set<Set<V>> combos

以下是输入的外观,

getCombos(alphabet, 5, myChars)

此方法应返回包含F和G的24 * 23 * 22(12144)个唯一5个字母组合。

这是我尝试过的,我觉得这可能已经过时了。

public static <V> HashSet<HashSet<V>> getCombos(HashSet<V> base, HashSet<V> elements, int size) {
    HashSet<HashSet<V>> combos = new HashSet<HashSet<V>>();
    HashSet<V> curr = new HashSet<V>(base);
    recur(curr, combos, base, elements, size);
    return combos;

}

public static <V> void recur(HashSet<V> curr, HashSet<HashSet<V>> combos, HashSet<V> base, HashSet<V> elements, int size) {
    if (curr.size() == size)
        combos.add(curr);
    else
        for (V v : elements) {
            curr.add(v);
            recur(curr, combos, base, elements, size);
            // This part below is where i feel like i'm going wrong and i'm not sure what to do
            curr = dupe(base);
            break;
        }
}

1 个答案:

答案 0 :(得分:1)

你的想法几乎是正确的,你只是在那里遇到了一些逻辑错误。希望这应该按照你想要的方式工作:

public static <V> HashSet<HashSet<V>> getCombos(HashSet<V> base, HashSet<V> elements, int size) {
    HashSet<HashSet<V>> combos = new HashSet<HashSet<V>>();
    HashSet<V> inner = dupe(base);
    inner.removeAll(elements);
    recur(elements, combos, inner, size);
    return combos;

}

public static <V> HashSet<V> dupe(HashSet<V> orig) {
    return new HashSet<V>(orig);
}

public static <V> void recur(HashSet<V> curr, HashSet<HashSet<V>> combos, HashSet<V> base, int size) {
    if (curr.size() == size) {
        combos.add(dupe(curr));
    } else {
        HashSet<V> inner = dupe(base);
        for (V v : base) {
            inner.remove(v);
            curr.add(v);
            recur(curr, combos, inner, size);
            curr.remove(v);
        }
    }
}

对于你给出的字母示例,它会正确地给出2024,因为你的12144号码包含了对于添加到FG的三个字母的每个组合的6个重新排序。