将数组拆分为指定最小大小的平衡块,较小的块在前面,较大的块在后面

问题描述 投票:0回答:1

在阅读了将数组分割成相等的块并将大块保留在最后之后,它不足以挑战最小的可验证示例,我注意到在唯一的、接受的答案中,它不够强大,无法将多余的元素分配到比最后一组更多的元素,因此尽可能平衡递增的最小尺寸的块。

例如,如果输入数组包含 8 个元素,则发布的答案将创建大小为 2、2 和 4 而不是 2、3 和 3 的不平衡子数组。

我想要一个功能:

  • 的作用类似于
    array_chunk()
    ,但是
  • 强制每个块指定最小数量的元素并且
  • 将努力创建平衡的数组大小并且
  • 将确保较早填充的块的大小永远不会大于稍后填充的块的大小。

边缘情况处理:如果最小块大小小于1或小于数组的计数,则抛出异常。

测试输入和 json 编码结果(为了简洁):

  1. $minChunk = 3; $array = range(1, 8);

    [[1,2,3,4],[5,6,7,8]]
    
  2. $minChunk = 4; $array = range(1, 11);

    [[1,2,3,4,5],[6,7,8,9,10,11]]
    
  3. $minChunk = 2; $array = range(1, 5);

    [[1,2],[3,4,5]]
    
  4. $minChunk = 3; $array = range(1, 9);

    [[1,2,3],[4,5,6],[7,8,9]]
    
  5. $minChunk = 7; $array = range(1, 13);

    [[1,2,3,4,5,6,7,8,9,10,11,12,13]]
    
  6. $minChunk = 1; $array = range(1, 4);

    [[1],[2],[3],[4]]
    
php arrays multidimensional-array split grouping
1个回答
0
投票

这是一种方法,它将计算适当的子数组大小并在循环填充结果数组时从后面消耗输入数组。

代码:(带有大量测试用例的演示

function littleEndianMinChunk(array $array, int $minChunkSize): array
{
    if ($minChunkSize < 1) {
        throw new InvalidArgumentException('$minChunkSize must be 1 or greater');
    }
    if ($minChunkSize < count($array)) {
        throw new InvalidArgumentException('$minChunkSize must not be less than the size of $array');
    }
    $result = [];
    while ($array) {
        $count = count($array);
        $modulus = $count % $minChunkSize;
        if (!$modulus) {
            array_unshift($result, ...array_chunk($array, $minChunkSize));
            break;
        }
        $expectedRemainingChunks = max(1, intdiv($count, $minChunkSize));
        $sizeIncrease = ceil($modulus / $expectedRemainingChunks);
        array_unshift($result, array_splice($array, -$minChunkSize - $sizeIncrease)); 
    }
    return $result;
}
© www.soinside.com 2019 - 2024. All rights reserved.