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]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章