根据给出的List集合,获取所有子集组合

本文介绍了一种使用递归算法来获取集合中所有可能的子集组合的方法。通过一个私有静态变量存储所有组合结果,并定义了一个递归函数,该函数接受已选择的元素、待选择的元素集合及子集大小作为参数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

public class Combin {

    // 集合中所有子集组合
    private static List<List<BigDecimal>> COMBINATION_SET = new ArrayList<>();
    /**
     * 用递归获取所有子集组合
     *
     * @param selector 选完的组合,初始化为空
     * @param oddsSet  待选组合
     * @param n        子集组合大小
     */
    private static void combination(List<BigDecimal> selector, List<BigDecimal> oddsSet, int n) {

        if (n == 0) {
            List<BigDecimal> tmp = new ArrayList<>();
            for (BigDecimal i : selector) {
                tmp.add(i);
            }
            COMBINATION_SET.add(tmp);
            return;
        }

        if (oddsSet.isEmpty()) {
            return;
        }

        // 选择第一个元素,将元素放入集合
        selector.add(oddsSet.get(0));
        // 从第二个元素开始选择,再选择两个
        combination(selector, oddsSet.subList(1, oddsSet.size()), n - 1); 

        // 不选择第一个元素
        selector.remove(selector.size() - 1);
        // 从第二个元素开始选择,选择两个
        combination(selector, oddsSet.subList(1, oddsSet.size()), n);
    }

}

 

### Java 实现 A 集合中随机 m 个数与 B 集合中随机 n 个数的所有组合 为了实现这一目标,可以从两个方面入手:一是如何从给定集合中随机选取指定数量的元素;二是如何生成这些选定元素之间的所有可能组合。 #### 方法一:利用 `Random` 类和列表操作来选择随机元素并构建组合 这种方法适用于较小规模的数据。首先定义两个输入集合 A 和 B,接着分别从中随机选出 m 和 n 个不同的元素,最后遍历这两个子集以形成所有的配对组合。 ```java import java.util.*; public class RandomCombination { public static List<List<String>> getRandomCombinations(List<Integer> setA, int mA, List<Character> setB, int nB) { // 创建副本以防修改原始集合 ArrayList<Integer> tempSetA = new ArrayList<>(setA); ArrayList<Character> tempSetB = new ArrayList<>(setB); Collections.shuffle(tempSetA); // 打乱顺序 Collections.shuffle(tempSetB); // 获取前mA个元素作为新的子集 List<Integer> subsetA = tempSetA.subList(0, Math.min(mA, tempSetA.size())); // 同样地获取前nB个字符组成另一个子集 List<Character> subsetB = tempSetB.subList(0, Math.min(nB, tempSetB.size())); List<List<String>> combinations = new ArrayList<>(); for (Integer num : subsetA) { for (Character ch : subsetB) { combinations.add(Arrays.asList(num.toString(), String.valueOf(ch))); } } return combinations; } public static void main(String[] args) { List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); List<Character> letters = Arrays.asList('a', 'b', 'c'); List<List<String>> result = getRandomCombinations(numbers, 3, letters, 2); for (var pair : result) { System.out.println(pair.get(0) + ", " + pair.get(1)); } } } ``` 此代码片段展示了如何创建一个函数 `getRandomCombinations()` 来接收四个参数——两个源集合及其对应的要抽取的数量,并返回由所选项目组成的字符串形式的组合列表[^1]。 #### 方法二:基于递归的方式枚举所有可能性 当需要考虑更复杂的场景时,比如不仅限于简单的一对一映射而是希望得到更加全面的结果,则可以采用递归来解决问题。这种方式能够覆盖更多的应用场景,特别是对于那些涉及多层嵌套结构的情况特别有用。 下面是一个例子说明怎样通过递归方式获得两组不同大小数组间的所有唯一组合: ```java class CombinationGenerator { private static final int SIZE_A = 5; // 假设集合A有5个成员 private static final int SIZE_B = 3; // 假设集合B有3个成员 private static Integer[] arrayA = {1, 2, 3, 4, 5}; private static Character[] arrayB = {'x', 'y', 'z'}; /** * @param selectedFromA 已经选择了多少来自第一个集合中的项 * @param startInA 下次应该从哪个索引处开始尝试选择下一个项(用于避免重复) */ private static void combine(int selectedFromA, int startInA, boolean[] usedForA, char[] currentSelectionOfB, int depth) { if (selectedFromA >= 3 || depth >= 2) { printCurrentState(selectedFromA, usedForA, currentSelectionOfB); return; } for (int i = startInA; i < SIZE_A && selectedFromA < 3; ++i) { if (!usedForA[i]) { usedForA[i] = true; for (char c : arrayB) { currentSelectionOfB[depth] = c; combine(selectedFromA + 1, i + 1, usedForA, currentSelectionOfB, depth + 1); } usedForA[i] = false; } } } private static void printCurrentState(int countSelectedFromFirstArray, boolean[] usageFlagsForFirstArray, char[] secondArrayChoices) { StringBuilder sb = new StringBuilder(); for (int j = 0; j < SIZE_A; ++j) if (usageFlagsForFirstArray[j]) sb.append(arrayA[j]).append(", "); sb.setLength(sb.length() - 2).append(" | "); for (int k = 0; k <= 1; ++k) sb.append(secondArrayChoices[k]).append(", "); sb.setCharAt(sb.length() - 2, '\u007C'); // 替换成竖线(|) System.out.println(sb.toString()); } public static void main(String[] arg) { combine(0, 0, new boolean[SIZE_A], new char[2], 0); } } ``` 这段程序实现了更为通用的功能,它允许用户自定义想要提取的具体数目以及参与运算的对象类型。这里假设我们总是想从集合A里挑三个数字出来跟集合B里的任意两个字母做匹配[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值