Массив делить / делить на значение - PullRequest
4 голосов
/ 18 ноября 2010
$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] суммирует до 32, а также $ a [1] и $ a [2]..

Ответы [ 3 ]

4 голосов
/ 18 ноября 2010
$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

Примечание: | означает divides.

0 голосов
/ 18 ноября 2010
$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

0 голосов
/ 18 ноября 2010
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
    )

)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...