php 将关联数组元素分布到每个组具有最大总和的组中

yv5phkfx  于 2023-01-04  发布在  PHP
关注(0)|答案(3)|浏览(113)

我需要将关联数组拆分为一组,每组不超过50个元素,可以将多个元素推入一个给定的组中,以确保在开始一个新组之前,该组达到50个元素。
样品输入:

$array = [
    '5' => 142,
    '2' => 57,
    '18' => 37
];

预期结果:

[
    ['5' => 50],
    ['5' => 50],
    ['5' => 42, '2' => 8],
    ['2' => 49, '18' => 1],
    ['18' => 36],
];
6yoyoihd

6yoyoihd1#

只是心理游戏

$line = [];
// Invert array
foreach($arr as $k=>$v) {
   $line = array_merge($line, array_fill(0, $v, $k));
}
// Split and count occurrences
$res = array_map('array_count_values', array_chunk($line, 50));
print_r($res);

demo

bihw5rsg

bihw5rsg2#

若要创建一个数组,其中每个条目的总和不超过给定的数量,可以使用迭代方法。
让我们从一个空数组和一个表示该数组的工作索引的变量开始,在遍历输入数组时,我们将最大可能的剩余量添加到新数组中,如果达到极限,我们将递增索引变量,只要输入数组还没有被完全浏览,我们就继续操作。
代码:

const MAX_SUM = 50;
$total  = []; // Store the new data
$curKey = 0;  // Store the current key of $total array.
foreach ($array as $key => $value) {
    while ($value) {
        // Get the current sum for the current key:
        $curSum = array_sum($total[$curKey] ?? []);

        // If the max was reached, we can go to the next key:
        if ($curSum == MAX_SUM) $curKey++;

        // Now, compute if the value to add (max to reach 50);
        $add = $value + $curSum > MAX_SUM // If above,
            ? MAX_SUM - $curSum           // got only the difference,
            : $value;                     // else, use the full value.

        // Add the value
        $total[$curKey][$key] = $add;

        // Finally, remove what we added just before.
        $value -= $add;
    }
}
print_r($total);

输出:

Array (
    [0] => Array (
            [5] => 50
        )
    [1] => Array (
            [5] => 50
        )
    [2] => Array (
            [5] => 42
            [2] => 8
        )
    [3] => Array (
            [2] => 49
            [18] => 1
        )
    [4] => Array (
            [18] => 36
        )
)

另请参见@mickmackusa的nice answer

neskvpey

neskvpey3#

我对这项任务的思路与@Syscall的"推送和消费"方法一致。
1.迭代输入数组以访问键和值。
1.使用一个内部循环重复处理当前值,直到它被减法完全消耗。只有在值减为零时才中断循环。

  • 每次通过内部循环时:
  • 计算组中所有值的当前总和,然后
  • 查找组中剩余的空间与值中剩余的空间之间的较小整数值;将所述整数推送到具有当前键组中;然后从当前值中减去该整数,然后
  • 如果当前组已达到其限制,则递增组密钥
  • 重复上述步骤,直到所有输入元素都减少到零。

代码:(Demo

$groupLimit = 50;  // declare as a variable to avoid "magic numbers" in code

$result = [];
$groupKey = 0; 
foreach ($array as $key => $value) {
    while ($value) {
        $sum = array_sum($result[$groupKey] ?? []);                           // get group sum
        $value -= $result[$groupKey][$key] = min($groupLimit - $sum, $value); // push key with limited value; decrease value
        $groupKey += ($sum + $result[$groupKey][$key] === $groupLimit);       // only increment group key if at $groupLimit
    }
}
var_export($result);

相关问题