Java根据Id快速最优分组

话不多说,都有注释直接上代码。

Integer[] userArr = {10000, 10001, 10002, 10003, 10004, 10005, 10006, 10007, 10008,
                10009, 10010, 10011, 10012, 10013, 10014, 10015,10016};
        List<Integer> memberList = Arrays.asList(userArr);
        //1.确认当前有多少组
        int groupCount = 4;
        //2.总人数
        int count = memberList.size();
        //3.确认每组人数
        int numbers = count / groupCount;
        //4.每组最小人数
        int average = numbers;
        //5.每组最大人数
        numbers = count % groupCount > 0 ? numbers + 1 : numbers;
        log.info("总人数为->{},分->{}组,每组最小人数为->{},每组最大人数为->{}", memberList.size(), groupCount, average, numbers);
        //平均分:每组开始抽人数,
        HashMap<Integer, List<Integer>> map = new HashMap<>();
        for (int i = 0; i < count; i++) {
            //当前元素已经不可加入的分组
            log.info("轮到->{}", memberList.get(i));
            ArrayList<Integer> joinTmp = new ArrayList<>();
            while (true) {
                //随机确认当前元素归属那一组
                int groupNum = new Random().nextInt(groupCount) + 1;
                log.info("随机加入的组为->{}", groupNum);
                //已经确认不能加入当前组了
                if (joinTmp.contains(groupNum)) {
                    log.info("已经加入了第{}组,重新选择", groupNum);
                    log.info("已经加入过{}", joinTmp);
                    if (joinTmp.size() >= groupCount) break;
                    continue;
                }
                //如果是第一次产生当前组,则当前元素就归属到这一组
                if (map.get(groupNum) == null) {
                    log.info("{}是第{}组第一个元素,所以加入了", memberList.get(i), groupNum);
                    List<Integer> list = new ArrayList<>();
                    list.add(memberList.get(i));
                    map.put(groupNum, list);
                    break;
                } else {
                    List<Integer> itemList = map.get(groupNum);
                    log.info("第{}组当前共有->{}个元素", groupNum, itemList.size());
                    //当前元素加入当前组的条件是:
                    // 1:当前组总人数要大于最小人数,小于等于最大人数,没有满足最小人数则可以加入
                    // 2:如果当前分组已经是满足了最小人数的话。
                    // 判断是否是多余的人数即:已经确认分过组的人数-(最小人数*分组数)>0,则当前元素是平均分多出来的人
                    // 例如:16个人,分3组,每组最小人数是5,最大人数是6,如果三组都分了5个人,已经确认分组了15人,则当前第16个人是多出来的
                    if (itemList.size() < average || ((i+1) - average * groupCount > 0)) {
                        log.info("第{}组满足条件,{}加入了", groupNum, memberList.get(i));
                        itemList.add(memberList.get(i));
                        map.put(groupNum, itemList);
                        break;
                    }
                    joinTmp.add(groupNum);
                }
            }
        }
        map.forEach((key, value) -> {
            log.info("第->{}组,共有->{}人数", key, value.size());
            log.info("第->{}组,人数:->{}", key, value);
        });

输出结果:

11:16:07.740 [main] INFO TestOne -->1,共有->4人数
11:16:07.741 [main] INFO TestOne -->1,人数:->[10008, 10009, 10010, 10015]
11:16:07.741 [main] INFO TestOne -->2,共有->5人数
11:16:07.741 [main] INFO TestOne -->2,人数:->[10001, 10002, 10006, 10013, 10016]
11:16:07.741 [main] INFO TestOne -->3,共有->4人数
11:16:07.741 [main] INFO TestOne -->3,人数:->[10000, 10003, 10005, 10007]
11:16:07.741 [main] INFO TestOne -->4,共有->4人数
11:16:07.741 [main] INFO TestOne -->4,人数:->[10004, 10011, 10012, 10014]
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值