按值将数组分割/拆分

4
$a = array(8, 16, 16, 32, 8, 8, 4, 4);

如果有像上面那样的数组,是否有一种方法可以根据总和等于设定值来分割/拆分数组。例如,如果我想让它们等于32。我的最终数组将具有多达100个值,所有这些值都是32、16、8或4,我只需要对项目进行分组,使值始终等于一个设定值,所以在这个例子中是32。

从上面的数组中,我希望得到:

$a[0][1] = 16
$a[0][2] = 16

$a[1][3] = 32

$a[2][0] = 8
$a[2][4] = 8
$a[2][5] = 8
$a[2][6] = 4
$a[2][7] = 4

由于$a[0]、$a[1]和$a[2]的总和均为32。


2
为什么你会得到[[16,16],[32],[8,8,8,4,4]]而不是例如[[32], [8,8,16], [4,4,8,16]]?或者这并不重要吗? - Matt Ellen
现在不管组成是什么,只要它们总和为32就可以了。对于造成的困惑我很抱歉。 - azzy81
赞同 - 只要总和为32,它们如何组合有关系吗?如果总和不是32的倍数怎么办? - Spudley
如果有多余的部分没有乘以,最好将其放在末尾的单独元素中。但是你完全正确,只要它们的总和为32,它们被分组的顺序并不重要。理想情况下,分组越随机越好,因为这些值是报纸广告的大小。 - azzy81
所以除了最后一个组之外,所有的组都需要恰好为32(一些背包问题的修改)? - AndreKR
显示剩余2条评论
3个回答

4
$a = array(8, 16, 16, 32, 8, 8, 4, 4);
$limit = 32;
rsort($a);
$b = array(array());
$index = 0;
foreach($a as $i){
    if($i+array_sum($b[$index]) > $limit){
        $b[++$index] = array();
    }
    $b[$index][] = $i;
}
$a = $b;
print_r($a);

这将起作用,但只有在您的情况下,您有4 | 8 | 16 | 32,并且仅当所需总和是最大数字(32)的倍数时才有效。

测试:http://codepad.org/5j5nl3dT

注意:|表示除以


“|”是一种位运算符,表示“或”,为什么你不直接写成“4/8/16/32”呢? - RobertPitt
@Robert,我指的是数学中使用的 | 符号。如果造成了困惑,我很抱歉。通过使用这种链接方式,我试图指出每个数字都可以被下一个数字整除。4 / 8 / 16 / 32 只等于 0,它并没有告诉你更多的信息。 - Alin Purcaru
没问题,很多成员包括我自己有时候会对位运算符感到困惑,只是确保没有混淆,代码块也很棒 :) +1 - RobertPitt

0
function split_into_thirtytwos($input_array) {
  $output_array=array();
  $work_array=array();
  $sum=0;
  sort($input_array,SORT_NUMERIC);
  while(count($input_array)>0) {
    $sum=array_sum($work_array)+$input_array[count($input_array)-1];
    if($sum<=32) {
        $work_array[]=array_pop($input_array);
    } else {
      $output_array[]=$work_array;
      $work_array=array();
    }
  }
  if(count($work_array)>0) {$output_array[]=$work_array;}
  return $output_array;
}

使用您的输入进行测试:

Array
(
  [0] => Array
    (
        [0] => 32
    )

  [1] => Array
    (
        [0] => 16
        [1] => 16
    )

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

)

0
$a = array(8, 16, 16, 32, 8, 8, 4, 4);
$group_limit = 32;


$current_group = $result = array();
$cycles_since_successful_operation = 0;

while ($a && $cycles_since_successful_operation < count($a))
{
    array_push($current_group,array_shift($a));

    if (array_sum($current_group) > $group_limit)
        array_push($a,array_pop($current_group));
    elseif (array_sum($current_group) < $group_limit)
        $cycles_since_successful_operation = 0;
    elseif (array_sum($current_group) == $group_limit)
    {
        $result []= $current_group;
        $current_group = array();
        $cycles_since_successful_operation = 0;
    }
}
if ($a)
    $result []= $a; // Remaining elements form the last group

http://codepad.org/59wmsi4g


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接