美文网首页
排列组合 n个数中取m个的数的组合 双色球

排列组合 n个数中取m个的数的组合 双色球

作者: jpc123 | 来源:发表于2019-05-24 20:24 被阅读0次

    http://itfish.net/article/50576.html
    计算出来双色球33选6个红球排列组合所有的组合,要求最小化算法时间。
    1,23,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33
    排列组合后总共有1107568中情况(1107568 = 33!/(33-6)!*6!)
    其中算法核心为:最小组合(1,2,3,4,5,6) , 最大组合(28,29,30,31,32,33), 每一组组合规律为 (A<B<C<D<E<F) 。
    1.扩展成 排列组合 n个数中取m个的数的组合结果
    2.根据用户选的结果统计各个组合的选中数量

    
    import java.util.*;
    
    /**
     * 排列组合
     *
     * @author 咋个办呢
     */
    public class PermutationsCombinations {
    
        /**
         * 递归算法核心
         *
         * @param pce
         * @param w
         * @param m
         */
        private static void calpce(int[] pce, int w, int m) {
            if (pce[w] + 1 > (m - pce.length + w + 1)) {
                if (w > 0) {
                    calpce(pce, w - 1, m);
                    pce[w] = pce[w - 1] + 1;
                } else {
                    pce[w] = pce[w] + 1;
                }
            } else {
                pce[w] = pce[w] + 1;
            }
        }
    /**计算从m个数选n个的组合数量  n<=m */
        private static int sumCount(int m, int n) {
            int a = 1, c = 1;
            for (int _m = m; _m > (m - n); _m--) {
                a = a * _m;
            }
            for (int _n = n; _n > 0; _n--) {
                c = c * _n;
            }
            return a / c;
        }
    
        public static void main(String[] args) {
            List<String> redAllType = redAllType();
            List<String> redBlue = addBlue(redAllType);
    
            test(redAllType);
        }
    
        static List<String> redAllType() {
            int all = 33;
            int take = 6;
            int[] pces = new int[all];
    
            for (int i = 0; i < pces.length; i++) {
                pces[i] = i + 1;
                if (i % 11 == 0) {
                    System.out.println();
                }
                System.out.print(pces[i] + ",");
            }
    
            System.out.println();
    
            int sumc = sumCount(all, take);
    
            System.out.println("排列组合后共有" + sumc + "个组合。");
    
            int[] pce = new int[take];
            for (int i = 0; i < take; i++) {
                pce[i] = i + 1;
    
            }
            int count = 0;
            long t1 = System.currentTimeMillis();
            ArrayList<String> redAllType = new ArrayList<>(sumc);
            while (count < sumc) {
                count++;
    //          System.out.println(String.format("[%d,%d,%d,%d,%d,%d]",pce[0],pce[1],pce[2],pce[3],pce[4],pce[5]));
    //            System.out.println(Arrays.toString(pce));
                redAllType.add(Arrays.toString(pce));
                calpce(pce, take - 1, all);
            }
            long t2 = System.currentTimeMillis();
    
            System.out.println("耗时:" + (t2 - t1) + "ms,计数总数:" + (count));
            return redAllType;
        }
    
        static List<String> addBlue(List<String> redAllType) {
            long t1 = System.currentTimeMillis();
            ArrayList<String> all = new ArrayList<>();
            int size = redAllType.size();
            for (int i = 1; i <= 16; i++) {
                for (int j = 0; j < size; j++) {
                    all.add(redAllType.get(j).replace("]", "," + i + "]"));
                }
            }
            long t2 = System.currentTimeMillis();
            System.out.println("添加篮球 耗时:" + (t2 - t1) + "ms,计数总数:" + (all.size())); //17721088
    //        System.out.println(all.toString());
            return all;
        }
    
    
        static void test(List<String> all) {
            int count = 10000 * 1000;// 假设有count 个人随机选了号码
            HashMap<String, KeyCount> allMap = new HashMap<>();
            int allCount = all.size();
            for (int i = 0; i < allCount; i++) {
                allMap.put(all.get(i), new KeyCount(all.get(i)));
            }
    
            //模拟选中的号码
            List<String> hasType = new ArrayList<>(count);
            Random random = new Random();
            for (int i = 0; i < count; i++) {
                hasType.add(all.get(random.nextInt(allCount)));
            }
            long t1 = System.currentTimeMillis();
            //统计 各种号码的个数
            for (int i = 0; i < count; i++) {
                allMap.get(hasType.get(i)).count++;
            }
    
            Collection<KeyCount> values = allMap.values();
            ArrayList<KeyCount> list = new ArrayList<>(values);
            Collections.sort(list, new Comparator<KeyCount>() {
                @Override
                public int compare(KeyCount arg0, KeyCount arg1) {
                    int count0 = arg0.count;
                    int count1 = arg1.count;
                    if (count0 > count1) {
                        return 1;
                    } else if (count0 == count1) {
                        return 0;
                    } else {
                        return -1;
                    }
                }
            });
    
            long t2 = System.currentTimeMillis();
            System.out.println("统计结果 耗时:" + (t2 - t1));
    
            for (int i = 0; i < allCount; i++) {
                    if(list.get(i).count>6){
                        break;
                    }
    
                System.out.println(list.get(i));
            }
        }
    
        static class KeyCount {
            public String key;
            public int count;
    
            public KeyCount(String key) {
                this.key = key;
            }
    
            @Override
            public String toString() {
                return "KeyCount{" +
                        "key='" + key + '\'' +
                        ", count=" + count +
                        '}';
            }
        }
    }
    
    
    

    相关文章

      网友评论

          本文标题:排列组合 n个数中取m个的数的组合 双色球

          本文链接:https://www.haomeiwen.com/subject/fvnnzqtx.html