【java/算法/组合】某校开设A类选修课3门,B类选修课4门,某同学从中共选3门。学校要求一类至少选一门,问不同选法有几种并请列举出具体选法。
【题干】
某校开设A类选修课3门,B类选修课4门,某同学从中共选3门。学校要求一类至少选一门,问不同选法有几种。
【数学解法】
只有两种情况:A类选一门B类选两门 和 A类选两门B类选一门
类别一:A类选一门B类选两门,C31*C42;(C31表示3中选1,以下类同)
类别二:A类选两门B类选一门,C32*C41;
总数Sum=C31*C42+C32*C41=3*4*3/2/1+3*2/2/1*4=18+12=30种
【代码解法】
做两个M选N的选择器,然后让结果一一配对。
选择器代码:
package test230422; import java.util.List; public class CourseSelector { public static void main(String[] args) { int idx=0;// 序号 String[] coursesA= {"孔孟哲学","老庄思想","法家规制"}; String[] coursesB= {"鲍鹏山讲水浒","吴闲云谈西游","王立群聊三国","刘心武扯红楼"}; for(int i=1;i<3;i++) { int aCnt=i; Combiner selectedA=new Combiner(coursesA,aCnt); List<List<String>> resultsA=selectedA.getResults(); int bCnt=3-i; Combiner selectedB=new Combiner(coursesB,bCnt); List<List<String>> resultsB=selectedB.getResults(); for(List<String> resA:resultsA) { for(List<String> resB:resultsB) { System.out.println(String.format("%02d", ++idx) +"."+resA+","+resB); } } } } }
组合器代码:
package test230422; import java.util.ArrayList; import java.util.List; /** * 从数组中选择有限个数的组合器 * 比如从abc中选2个,会产生ab,ac,bc的结果 */ public class Combiner { /** * 选择的结果 */ private List<List<String>> results; /** * 构造函数 * @param candidates 候选者名单 * @param selectCnt 选择的数量 */ public Combiner(String[] candidates,int selectCnt) { int nCnt = candidates.length; if(selectCnt>nCnt) { throw new ArrayIndexOutOfBoundsException(selectCnt+">"+nCnt); } results=new ArrayList<>(); int nBit = (0xFFFFFFFF >>> (32 - nCnt)); for (int i = 1; i <= nBit; i++) { List<String> ls=new ArrayList<>(); for (int j = 0; j < nCnt; j++) { if ((i << (31 - j)) >> 31 == -1) { ls.add(candidates[j]); } } if(ls.size()==selectCnt) { results.add(ls); } } } /** * 取得选择的结果 * @return */ public List<List<String>> getResults(){ return results; } /** * 使用示例 * @param args */ public static void main(String[] args) { String[] arr= {"A","B","C"}; Combiner c=new Combiner(arr,2); List<List<String>> results=c.getResults(); for(List<String> ls:results) { System.out.println(ls); } } }
【运行结果】
01.[孔孟哲学],[鲍鹏山讲水浒, 吴闲云谈西游] 02.[孔孟哲学],[鲍鹏山讲水浒, 王立群聊三国] 03.[孔孟哲学],[吴闲云谈西游, 王立群聊三国] 04.[孔孟哲学],[鲍鹏山讲水浒, 刘心武扯红楼] 05.[孔孟哲学],[吴闲云谈西游, 刘心武扯红楼] 06.[孔孟哲学],[王立群聊三国, 刘心武扯红楼] 07.[老庄思想],[鲍鹏山讲水浒, 吴闲云谈西游] 08.[老庄思想],[鲍鹏山讲水浒, 王立群聊三国] 09.[老庄思想],[吴闲云谈西游, 王立群聊三国] 10.[老庄思想],[鲍鹏山讲水浒, 刘心武扯红楼] 11.[老庄思想],[吴闲云谈西游, 刘心武扯红楼] 12.[老庄思想],[王立群聊三国, 刘心武扯红楼] 13.[法家规制],[鲍鹏山讲水浒, 吴闲云谈西游] 14.[法家规制],[鲍鹏山讲水浒, 王立群聊三国] 15.[法家规制],[吴闲云谈西游, 王立群聊三国] 16.[法家规制],[鲍鹏山讲水浒, 刘心武扯红楼] 17.[法家规制],[吴闲云谈西游, 刘心武扯红楼] 18.[法家规制],[王立群聊三国, 刘心武扯红楼] 19.[孔孟哲学, 老庄思想],[鲍鹏山讲水浒] 20.[孔孟哲学, 老庄思想],[吴闲云谈西游] 21.[孔孟哲学, 老庄思想],[王立群聊三国] 22.[孔孟哲学, 老庄思想],[刘心武扯红楼] 23.[孔孟哲学, 法家规制],[鲍鹏山讲水浒] 24.[孔孟哲学, 法家规制],[吴闲云谈西游] 25.[孔孟哲学, 法家规制],[王立群聊三国] 26.[孔孟哲学, 法家规制],[刘心武扯红楼] 27.[老庄思想, 法家规制],[鲍鹏山讲水浒] 28.[老庄思想, 法家规制],[吴闲云谈西游] 29.[老庄思想, 法家规制],[王立群聊三国] 30.[老庄思想, 法家规制],[刘心武扯红楼]
数学解答和程序输出可以相互验证。
END