如何将n长度的数组划分为大小大致相等的k个子数组(在C中)?

时间:2016-11-20 19:24:06

标签: c arrays sub-array

我有一个大小为n的数组,想要分成k个子数组,每个数组的大小必须大致相同。我已经思考了一段时间,并且知道你必须使用两个for循环,但我很难实现这些for循环。

我尝试过的事情:

//Lets call the original integer array with size n: arr
// n is the size of arr
// k is the number of subarrays wanted

int size_of_subArray = n/k;
int left_over = n%k; // When n is not divisible by k
int list_of_subArrays[k][size_of_subArray + 1];

//Lets call the original integer array with size n: arr

for(int i = 0; i < k; i++){
   for(int j = 0; j < size_of_subArray; j++){
       list_of_subArrays[i][j] = arr[j];
   }
}

我正在努力在forloops中获取正确的索引。

任何想法?

1 个答案:

答案 0 :(得分:0)

我已经重构了您的代码并对其进行了注释。

要点是:

  1. 计算子阵列大小时,必须将其向上舍入
  2. arr的索引需要从0继续增加(即 重置为0)
  3. 以下应该有效,但我没有测试[请原谅无偿的风格清理]:

    // Lets call the original integer array with size n: arr
    //  n is the size of arr
    //  k is the number of subarrays wanted
    
    // round up the size of the subarray
    int subsize = (n + (k - 1)) / k;
    
    int list_of_subArrays[k][subsize];
    
    int arridx = 0;
    int subno = 0;
    
    // process all elements in original array
    while (1) {
        // get number of remaining elements to process in arr
        int remain = n - arridx;
    
        // stop when done
        if (remain <= 0)
            break;
    
        // clip remaining count to amount per sub-array
        if (remain > subsize)
            remain = subsize;
    
        // fill next sub-array
        for (int subidx = 0; subidx < remain; ++subidx, ++arridx)
            list_of_subArrays[subno][subidx] = arr[arridx];
    
        // advance to next sub-array
        ++subno;
    }
    

    <强>更新

      

    是的,这会将数组划分为n个子阵列,但它并没有均匀划分。假设有一个大小为10的数组,并希望将其划分为9个子阵列。那么8个子阵列将拥有1个原始数组的元素,但是一个子阵列需要有2个元素。

    您的原始代码有一些错误[已在上例中修复]。即使我自己这样做,上面也是让工作变得有效的第一步。

    在原始问题中,您 说:&#34;并且每个数组必须大约相同的大小&#34;。但是,这里有列表子数组的物理大小[仍为舍入值]。

    但是,我可能已经说过像#34;均匀分布的&#34;或某些此类进一步澄清您的意图。也就是说,你希望的最后一个子阵列/桶是&#34;短&#34; [大幅度]。

    鉴于此,代码开始时有点相同,但需要更复杂一点。这仍然有点粗糙,可能会进一步优化:

    #include <stdio.h>
    
    #ifdef DEBUG
    #define dbgprt(_fmt...)     printf(_fmt)
    #else
    #define dbgprt(_fmt...)     /**/
    #endif
    
    int arr[5000];
    
    // Lets call the original integer array with size n: arr
    //  n is the size of arr
    //  k is the number of subarrays wanted
    
    void
    fnc2(int n,int k)
    {
        // round up the size of the subarray
        int subsize = (n + (k - 1)) / k;
    
        int list_of_subArrays[k][subsize];
    
        dbgprt("n=%d k=%d subsize=%d\n",n,k,subsize);
    
        int arridx = 0;
    
        for (int subno = 0;  subno < k;  ++subno) {
            // get remaining number of sub-arrays
            int remsub = k - subno;
    
            // get remaining number of elements
            int remain = n - arridx;
    
            // get maximum bucket size
            int curcnt = subsize;
    
            // get projected remaining size for using this bucket size
            int curtot = remsub * curcnt;
    
            // if we're too low, up it
            if (curtot < remain)
                ++curcnt;
    
            // if we're too high, lower it
            if (curtot > remain)
                --curcnt;
    
            // each bucket must have at least one
            if (curcnt < 1)
                curcnt = 1;
    
            // each bucket can have no more than the maximum
            if (curcnt > subsize)
                curcnt = subsize;
    
            // last bucket is the remainder
            if (curcnt > remain)
                curcnt = remain;
    
            dbgprt("  list[%d][%d] --> arr[%d] remain=%d\n",
                subno,curcnt,arridx,remain);
    
            // fill next sub-array
            for (int subidx = 0; subidx < curcnt; ++subidx, ++arridx)
                list_of_subArrays[subno][subidx] = arr[arridx];
        }
    
        dbgprt("\n");
    }