将C数组拆分为n个相等的部分

时间:2016-04-10 05:39:13

标签: c arrays

我试图通过计算开始和结束索引将数组分成n个相等的部分。 start和end元素的地址将被传递给一个对这些数组进行排序的函数。例如,如果arraySize = 1000,并且n = 2,则索引将为0,499,999。到目前为止,我有以下代码,但对于奇数n,它将它分成多于n个数组。我想到这样做的另一种方法是通过循环运行n次,但我不知道从哪里开始。

  int chunkSize = arraySize / numThreads;
  for (int start = 0; start < arraySize; start += chunkSize) {
      int end = start + chunkSize - 1;
      if (end > arraySize - 1) {
          end = arraySize - 1;
      }

      InsertionSort(&array[start], end - start + 1);
  }

编辑:这是我想出的其他内容。它似乎有效,但我需要做一些更全面的测试。我已经多次抽出它并手工追踪它。希望没有任何边缘情况会失败。我已经限制了n&gt; = arraySize。

int chunkSize = arraySize / numThreads;
for (int i = 0; i < numThreads; i++) {
    int start = i * chunkSize;
    int end = start + chunkSize - 1;
    if (i == numThreads - 1) {
        end = arraySize - 1;
    }

    for (int i = start; i <= end; i++) {
        printf("%d ", array[i]);
    }
        printf("\n");
}

3 个答案:

答案 0 :(得分:2)

使用截断除法计算最小块大小。然后计算余数。通过在某些块中添加1来分配此余数:

的伪代码:

chunk_size = array_size / N
bonus = array_size - chunk_size * N  // i.e. remainder

for (start = 0, end = chunk_size;
     start < array_size;
     start = end, end = start + chunk_size)
{
  if (bonus) {
    end++;
    bonus--;
  }

  /* do something with array slice over [start, end) interval */
}

例如,如果array_size为11且N == 4,则11 / N产生2.余数(“奖励”)为3:11 - 2*3。因此,循环的前三次迭代将增加1到大小:3 3 3.奖金然后达到零,最后一个块大小将只是2.

我们在这里所做的只不过是以一种令人满意的方式在离散量化中分配误差项。这正是使用Bresenham算法在光栅显示器上绘制线段时,或者使用Floyd-Steinberg抖动等将图像缩小为较少数量的颜色时所发生的情况。

答案 1 :(得分:1)

您需要计算您的块大小,以便它“向上舍入”,而不是向下。您可以使用%运算符和更复杂的公式来执行此操作,但只使用简单的if可能更容易理解:

int chunkSize = arraySize / numThreads;
if (chunkSize * numThreads < arraySize) {
    // In case arraySize is not exactly divisible by numThreads,
    // we now end up with one extra smaller chunk at the end.
    // Fix this by increseing chunkSize by one byte,
    // so we'll end up with numThread chunks and smaller last chunk.
    ++chunkSize;
}

答案 2 :(得分:0)

我希望这会有所帮助:

int chunkSize = arraySize / numThreads;
  for (int i = 0; i < numThreads-1; i++) {
      start = i* chunkSize;
      end = start + chunkSize - 1;
      InsertionSort(&array[start], end + 1);
  }
  //Last chunk with all the remaining content
  start = end + 1;
  end = arraySize - 1;
  InsertionSort(&array[start], end + 1);