【问题标题】:How can I split an array of numbers evenly如何均匀地拆分一组数字
【发布时间】:2015-11-18 19:56:41
【问题描述】:

假设我有数组:

array(1,1,2,1,4,5,7,2,3);

将这些数字放入 x 数组中的最快方法是什么,我们将使用 3 并让数字与最后更大的数字尽可能相等?

例子:

array(1, 1, 1, 5);
array(7, 2);
array(4, 2, 3);

我担心这可能是一个 p=np 问题,但它看起来很简单,不应该是这样。我就是想不通。

类似问题:Algorithm to split an array into P subarrays of balanced sum

【问题讨论】:

  • 你输出的依据是什么?写得怎么样?
  • 你说的后面的数字越大是什么意思
  • 第一个数组中的数字总数为 26,所以应该有两个总数为 9 和一个总数为 8,这是我输出的基础。我不知道如何有效地实现这一目标
  • 好吧,效率低下,我们会努力提高效率。
  • 不要删除并重新发布相同的问题。这很粗鲁。

标签: php arrays sorting numbers


【解决方案1】:

不完全是您正在寻找的东西,但这应该可以帮助您入门:

$array = array(1,1,2,1,4,5,7,2,3);

asort($array);

$total = array_sum($array);

$array1 = array();
$array2 = array();
$array3 = array();

foreach($array as $number) {
    if(array_sum($array1) < round($total / 3)) {
        array_push($array1, $number);
    } elseif(array_sum($array2) < round($total / 3)) {
        array_push($array2, $number);
    } else {
        array_push($array3, $number);
    }
}

for($i = 1; $i <= 3; $i++) {

    switch($i) {
        case 1:
            $op1 = 2;
            $op2 = 1;
            break;
        case 2:
            $op1 = -1;
            $op2 = 1;
            break;
        case 3:
            $op1 = -2;
            $op2 = -1;
            break;
    }

    foreach(${'array' . $i} as $number) {
        if((array_sum(${'array' . ($i + $op1)}) + $number) == round($total / 3)) {
            unset(${'array' . $i}[array_search($number, ${'array' . $i})]);
            array_push(${'array' . ($i + $op1)}, $number);
        } elseif((array_sum(${'array' . ($i + $op2)}) + $number) == round($total / 3)) {
            unset(${'array' . $i}[array_search($number, ${'array' . $i})]);
            array_push(${'array' . ($i + $op2)}, $number);
        }
    }
}

print_r($array1);
print_r($array2);
print_r($array3);

新输出:

Array
(
    [0] => 1
    [1] => 1
    [2] => 1
    [4] => 2
    [5] => 3
)
Array
(
    [0] => 4
    [1] => 5
)
Array
(
    [0] => 7
    [1] => 2
)

【讨论】:

  • 这与我实际寻找的非常接近。
  • 添加了更多排序以获得所需的结果。
【解决方案2】:

基本上,您可以使用array_slice 去除您需要的块,并使用asort 将数组从最小到最大排序。

下面的代码可以解决问题:

(编辑:在最近的评论之后我很困惑,您是说您希望数组中的数字总和接近相同吗?我以为您的意思是您希望数组的大小均匀分布而不是总和?)

$arr = array(1,1,2,1,4,5,7,2,3);
asort($arr); // sort the array

$x = 3; // number of arrays
$offset = ceil(count($arr) / $x);

$newArrays = array();
for($i=0;$i<=count($arr)-1;$i+=$offset) {
  $newArrays[] = array_slice($arr,$i,$offset);
}

var_dump($newArrays);

结果:

array(3) {
  [0]=>
  array(3) {
    [0]=>
    int(1)
    [1]=>
    int(1)
    [2]=>
    int(1)
  }
  [1]=>
  array(3) {
    [0]=>
    int(2)
    [1]=>
    int(2)
    [2]=>
    int(3)
  }
  [2]=>
  array(3) {
    [0]=>
    int(4)
    [1]=>
    int(5)
    [2]=>
    int(7)
  }
}

【讨论】:

  • 几个小时前同一用户问了同样的问题,就在我想发布答案时,问题被删除了......无论如何,我使用的逻辑与您相同,除了我们可以使用 array_chunk($array, $offset); 而不是for 循环。 :)
  • 我实际上是在尝试让数组 1-3 具有相似的总数。很抱歉与“最后的较大数字”混淆。我的意思是,对于总共 26 个数组,你将有两个数组,总共 9 个数组,一个数组总共 8 个数组。我希望输出的方式是数组 1 的总数为 8,数组 2 和 3 有一共9个
  • 按总和平均分配。我正在尝试将一个数组拆分为 P 个平衡和的子数组。 IE 每个子阵列的总数大致相同。
猜你喜欢
  • 1970-01-01
  • 2013-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-05
  • 2019-09-01
  • 2021-06-03
  • 2017-01-09
相关资源
最近更新 更多