java 均勻分割數(shù)組或集合

需求:假設(shè)文件夾內(nèi)有多個小文件需要拆分給多個服務(wù)器處理,拆分盡量均勻順序不能亂。

入?yún)ist 是需要分割的數(shù)組,groups 是需要分割多少份,limits 是函數(shù)返回第幾份。
思路是,數(shù)組長度除groups ,余數(shù)中每一個元素均勻分配到組。因為groups一定大于等于余數(shù),組的pageSize加1,一定可全部分擔(dān)所有余數(shù)。
1、 list.length % group == 0 是剛好均分,那么 pageSize = list.length / group
2、(list.length % group)>= groupLimit,說明還有余數(shù)沒有均分完成,所以 pageSize = (list.length / group) + 1
3、有余數(shù)且余數(shù)均分完成,skip 要等于之前均分余數(shù)的組長度加上無需均分余數(shù)的組長度

 public static String[] groupFilter(String[] list, String groups, String groupLimits) {
        if (list == null || list.length == 0) {
            return list;
        }
        if (!NumberUtils.isParsable(groups) || !NumberUtils.isParsable(groupLimits)) {
            return list;
        }
        int group = Integer.parseInt(groups);
        int groupLimit = Integer.parseInt(groupLimits);
        if (group <= 1 || groupLimit <= 0 || groupLimit > group) {
            return list;
        }
        int pageSize = list.length / group;
        int mod = list.length % group;
        int skip = 0;
        if(mod == 0){//剛好均分
            skip = pageSize * (groupLimit - 1);
        }else if (mod >= groupLimit) {//有余數(shù)均分余數(shù)
            pageSize = pageSize + 1;
            skip = pageSize * (groupLimit - 1);
        } else {//有余數(shù)且余數(shù)均分完成
            skip = ((pageSize + 1) * mod)  + (pageSize * (groupLimit - mod - 1));
        }
        return Arrays.stream(list).sorted().skip(skip).limit(pageSize).toArray(String[]::new);
    }

一個整數(shù)數(shù)組,長度為n,將其分為m 份,使各份的和相等,求m 的最大值
比如數(shù)組:{3,2,4,3,6}
m=1,可以分成{3,2,4,3,6} ;
m=2,可以分成{3,6}{2,4,3}
m=3,可以分成{3,3}{2,4}{6}
所以m 的最大值為3

  • 思路:
  • 條件1: 均勻拆分
  • 推論1: 對每個分組求和一定分別相等 , 分組數(shù)量*每個分組的和 = 原數(shù)組和
  • 推論2: 每個分組的和 = 原數(shù)組和/分組數(shù)量,不能出現(xiàn)余數(shù)
  • 推論3:分組數(shù)量最多一定是原數(shù)組的長度,可以從最大開始循環(huán)
  • 根據(jù)三條推論,有如下程序。
   @Test
    private static void test3() {
        int[] a = { 3, 2, 4, 3, 6 };
        int sum = Arrays.stream(a).sum();
        //遍歷所有可能的分組個數(shù)
        for (int quantity = a.length; quantity > 1; quantity--) {
            //無法均分
            if (sum % quantity != 0)
                continue;
            //每個組的數(shù)值和
            int groupSum =  sum / quantity;
            //當(dāng)前組未分配的數(shù)值
            int groupUnassigned  = sum / quantity;
            if (test(a,  new int[a.length], quantity, groupSum,  groupUnassigned, 1)) {
                System.out.println("The Max m is:" + quantity);
                break;
            }
        }
    }

    /**
     *
     * @param a 原數(shù)組
     * @param allocate  記錄已經(jīng)分配的元素
     * @param quantity 分組總個數(shù)
     * @param groupSum 每個組的數(shù)值和
     * @param groupUnassigned 當(dāng)前組未分配的數(shù)值
     * @param groupLimit 當(dāng)前分組位移
     * @return false 分配失敗, true 分配成功
     */
    private static boolean test(int[] a, int[] allocate,  int quantity, int groupSum,
                                int groupUnassigned, int groupLimit) {
        // 說明加上當(dāng)前元素后數(shù)小組元素的和過大
        if (groupUnassigned < 0) {
            return false;
        }
        //當(dāng)前組分配完成
        if (groupUnassigned == 0) {
            groupLimit++;
            groupUnassigned = groupSum;
            //所有組分配完成
            if (groupLimit == quantity + 1) {
                return true;
            }
        }

        for (int i = 0; i < allocate.length; i++) {
            //元素已經(jīng)被分配了
            if (allocate[i] != 0)
                continue;

            //預(yù)分配
            allocate[i] = groupLimit;

            if (test(a, allocate,  quantity, groupSum, groupUnassigned - a[i], groupLimit))
                return true;

            // 當(dāng)前元素分配失敗,置回初始狀態(tài)
            allocate[i] = 0;
        }

        return false;
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容