【问题标题】:How to find all subsets of a specified length?如何找到指定长度的所有子集?
【发布时间】:2022-02-03 18:16:57
【问题描述】:

我在previous question 中询问过这个问题。我想找到指定长度的所有子集。

Damien 用 C++ 给我写了一个nice answer,我正在尝试转换它,但没有运气。这是我的尝试:

import java.util.*;

public class Subset {
    void getSubsetAux(ArrayList<ArrayList<Integer>> s, int n, int k, int i,
                      ArrayList<Integer> dom, ArrayList<Integer> cs) {
        if(n<k) return;
        if(k == 0) {
            s.add(cs);
            return;
        }

        getSubsetAux(s, n-1, k, i+1, dom, cs);
        cs.add(dom.get(i));
        getSubsetAux(s, n-1, k-1, i+1, dom, cs);
        cs.remove(cs.size() -1);
    }

    void getSubset(ArrayList<ArrayList<Integer>> s, int l, ArrayList<Integer> dom) {
        ArrayList<Integer> cs = new ArrayList<>();
        getSubsetAux(s, dom.size(), l, 0, dom, cs);
    }

    public void print(ArrayList<ArrayList<Integer>> l) {
        for (ArrayList<Integer> el: l) {
            System.out.println(el);
        }
    }

    public void run(String[] args) {
        ArrayList<Integer> dom = new ArrayList<>(Arrays.asList(1,2,3,4,5));
        ArrayList<ArrayList<Integer>> ret = new ArrayList<ArrayList<Integer>>();

        getSubset(ret, 3, dom);

        print(ret);
    }

    public static void main(String [] args) {
        Subset s = new Subset();
        s.run(args);
    }
}

输出:

[]
[]
[]
[]
[]
[]
[]
[]
[]
[]

预期输出:(不一定是这个顺序)

[3, 4, 5]
[2, 4, 5] 
[2, 3, 5] 
[2, 3, 4] 
[1, 4, 5] 
[1, 3, 5] 
[1, 3, 4] 
[1, 2, 5] 
[1, 2, 4] 
[1, 2, 3] 

我认为这与我不了解 Java 中的输出参数有关

【问题讨论】:

    标签: java list set subset


    【解决方案1】:

    正如here 解释的那样, 您正在向外部列表多次添加对同一内部 ArrayList 的引用。因此,当您更改内部列表时,您会在所有内部列表中看到它。

    为了得到你想要的结果,你应该创建一个新的临时内部列表:

    if(k == 0) {
          ArrayList<Integer> temp = new ArrayList<Integer>(cs); 
          s.add(temp);
          return;
    }
    

    【讨论】:

    • 甜!非常感谢!
    【解决方案2】:

    如果您只对结果感兴趣而不是算法本身,您可以使用像 CombinatoricsLibGuavaApache Commons 这样的库:

    使用 CombinatoricsLib 代码可以很简单:

    List<Integer> dom = Arrays.asList(1,2,3,4,5);
    Generator.combination(dom)
             .simple(3)
             .stream()
             .forEach(System.out::println);
    

    输出:

    [1, 2, 3]
    [1, 2, 4]
    [1, 2, 5]
    [1, 3, 4]
    [1, 3, 5]
    [1, 4, 5]
    [2, 3, 4]
    [2, 3, 5]
    [2, 4, 5]
    [3, 4, 5]
    

    但如果你有兴趣自己实现算法,可能这篇文章是神读:https://www.baeldung.com/java-combinations-algorithm

    【讨论】:

    • 非常感谢,但我无法使用 3rd 方库。至少如果他们那么大,就不会。 :)
    猜你喜欢
    • 2021-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-05
    • 1970-01-01
    相关资源
    最近更新 更多