使用递归实现多个集合取不同元素生成多种组合

使用递归实现读个集合取不同元素生成多种组合

多种组合其实有很多种办法,递归是一种,还有我知道的笛卡尔积也是能够来实现这种需求

软件使用:idea
jdk版本:1.8

递归

递归:你打开面前这扇门,看到屋里面还有一扇门(这门可能跟前面打开的门一样大小(静),
        也可能门小了些(动)),你走过去,发现手中的钥匙还可以打开它,你推开门,发现里面还有一扇门,
        你继续打开,。。。, 若干次之后,你打开面前一扇门,发现只有一间屋子,没有门了。 你开始原路返回,
        每走回一间屋子,你数一次,走到入口的时候,你可以回答出你到底用这钥匙开了几扇门。

循环:你打开面前这扇门,看到屋里面还有一扇门,(这门可能跟前面打开的门一样大小(静),
       	   也可能门小了些(动)),你走过去,发现手中的钥匙还可以打开它,你推开门,发现里面还有一扇门,
       	   (前面门如果一样,这门也是一样,第二扇门如果相比第一扇门变小了,这扇门也比第二扇门变小了
       	   (动静如一,要么没有变化,要么同样的变化)),你继续打开这扇门,。。。,一直这样走下去。
       	    入口处的人始终等不到你回去告诉他答案。

废话不多说直接上核心代码:

class fun{
    public static <T> List<List<T>>getDescartes (List<List<T>>list){
        List<List<T>>returnList = new ArrayList<>();
        descartesRecursive(list,0,returnList,new ArrayList<>());
        return returnList;
    }   
    /**
     * 使用递归实现
     * @param originList 原始list
     * @param position   集合中位置
     * @param returnList 返回组装集合
     * @param cacheList  临时集合
     */
    private static <T> void descartesRecursive(List<List<T>>originList,int position,List<List<T>>returnList,List<T>cacheList){
        List<T> originChildList = originList.get(position);
        for (int i = 0; i<originChildList.size();i++){
            List<T> cacheChildList = (i==originChildList.size()-1)?cacheList:new ArrayList<>(cacheList);
            cacheChildList.add(originChildList.get(i));
            if(position==originList.size()-1){
                returnList.add(cacheChildList);
                continue;
            }
            descartesRecursive(originList,position+1,returnList,cacheChildList);
        }
    }
}
    ```

然后我们进行方法调用测试

 public static void main(String[] args) {
        List<String>oneList = Stream.of("1","2","3").collect(Collectors.toList());
        List<String>twoList = Stream.of("a","b","c").collect(Collectors.toList());
        List<String>threeList = Stream.of("@","#","$").collect(Collectors.toList());
        List<String>fourList = Stream.of("/","*","-").collect(Collectors.toList());
        List<List<String>>list = new ArrayList<>();
        list.add(oneList);
        list.add(twoList);
        list.add(threeList);
        list.add(fourList);
        List<List<String>>returnList = fun.getDescartes(list);
        returnList.forEach(System.err::println);
    }

接着我们查看结果:

[1, a, @, /]
[1, a, @, *]
[1, a, @, -]
[1, a, #, /]
[1, a, #, *]
[1, a, #, -]
[1, a, $, /]
[1, a, $, *]
[1, a, $, -]
[1, b, @, /]
[1, b, @, *]
[1, b, @, -]
[1, b, #, /]
[1, b, #, *]
[1, b, #, -]

以上就是整个代码输出的结果,希望对读者能够提供帮助。这是我最欣慰的结果。

我就是我,还在代码路途前走的小猿。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本书是系统阐述组合数学基础、理论、方法和实例的优秀教材,出版近30年来多次改版,被MIT、哥伦比亚大学、UIUC、威斯康星大学等众多国外高校采用,对国内外组合数学教学产生了较大影n向,也是相关学科的主要参考文献之一。 本书侧重于组合数学的概念和思想,包括鸽巢原理、计数技术、排列组合、Polya计数法、二项式系数、容斥原理、生成函数和递推关系以及组合结构(匹配、实验设计、图)等,深入浅出地表达了作者对该领域全面和深刻的理解,介绍了历史上源于数学游戏和娱乐的大量实例,其中对Polya计数、Burnside定理等的完美处理使得不熟悉群论的学生也能够读懂。除包含第3版中的内容外,本版又进行了更新,增加了莫比乌斯反演(作为容斥原理的推广)、格路径、Schroder数等内容。此外,各章均包含大量练习题,并在书末给出了参考答案与提示。 目录回到顶部↑ 出版者的话 专家指导委员会 译者序 前言 第1章 什么是组合数学 1.1 例:棋盘的完美覆盖 1.2 例:切割立方体 1.3 例:幻方 1.4 例:四色问题 1.5 例:36军官问题 1.6 例:最短路径问题 1.7 例:nim子游戏 1.8 练习题 第2章 鸽巢原理 2.1 鸽巢原理:简单形式 2.2 鸽巢原理:加强形式 2.3 ramsey定理 2.4 练习题 第3章 排列与组合 3.1 四个基本的计数原理 .3.2 集合的排列 3.3 集合组合 3.4 多重集的排列 3.5 多重集的组合 3.6 练习题 第4章 生成排列和组合 4.1 生成排列 4.2 排列中的逆序 4.3 生成组合 4.4 生成组合 4.5 偏序和等价关系 4.6 练习题 第5章 二项式系数 5.1 pascal公式 5.2 二项式定理 5.3 一些恒等式 5.4 二项式系数的单峰性 5.5 多项式定理 5.6 牛顿二项式定理 5.7 再论偏序集 5.8 练习题 第6章 容斥原理及应用 6.1 容斥原理 6.2 具有重复的组合 6.3 错位排列 6.4 带有禁止位置的排列 6.5 另外的禁排位置问题 6.6 莫比乌斯反演 6.7 练习题 第7章 递推关系和生成函数 7.1 一些数列 7.2 线性齐次递推关系 7.3 非齐次递推关系 7.4 生成函数 7.5 递归生成函数 7.6 一个几何的例子 7.7 指数生成函数 7.8 练习题 第8章 特殊计数序列 8.1 catalan数 8.2 差分序列和stirling数 8.3 分拆数 8.4 一个几何问题 8.5 格路径和schroder数 8.6 练习题 第9章 二分图中的匹配 9.1 一般问题表述 9.2 匹配 9.3 互异代表系统 9.4 稳定婚姻 9.5 练习题 第10章 组合设计 10.1 模运算 10.2 区组设计 10.3 steiner三元系统 10.4 拉丁方 10.5 练习题 第11章 图论导引 11.1 基本性质 11.2 欧拉迹 11.3 hamilton路径和hamilton圈 11.4 二分多重图 11.5 树 11.6 shannon开关游戏 11.7 再论树 11.8 练习题 第12章 有向图及网络 12.1 有向图 12.2 网络 12.3 练习题 第13章 再论图 13.1 色数 13.2 平面和平面图 13.3 五色定理 13.4 独立数和团数 13.5 连通性 13.6 练习题 第14章 polya计数法 14.1 置换群与对称群 14.2 burnside定理 14.3 polya计数公式 14.4 练习题 练题的答案与提示 参考文献 索引

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值