【问题标题】:Array divide/split by value数组按值除/拆分
【发布时间】:2010-11-18 16:20:37
【问题描述】:
$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] 也是如此。

【问题讨论】:

  • 为什么你会得到[[16,16],[32],[8,8,8,4,4]] 而不是[[32], [8,8,16], [4,4,8,16]]?还是没关系?
  • 不管组是由什么组成的,只要它们的总和为 32,抱歉造成混淆。
  • 第二 - 只要总计 32 个,它们的组合方式是否重要?如果总数不是 32 的倍数怎么办?
  • 看起来像一个魔方:en.wikipedia.org/wiki/Magic_square
  • 如果有一个多余的东西不能成倍增加,那么只要在最后一个单独的元素中看到它就好了。但是,是的,您完全正确,只要它们的总和为 32,它的组中的哪些项目并不重要。理想情况下,分组越随机越好,因为这些值是报纸中广告的大小。

标签: php arrays function


【解决方案1】:
$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

【讨论】:

  • | 是位运算符,意思是OR,你为什么不做4 / 8 / 16 / 32
  • @Robert 我指的是数学中使用的|。抱歉,如果它造成了混乱。通过使用该链接,我试图指出每个数字除以下一个数字。 4 / 8 / 16 / 32 只等于 O 它不会告诉你更多信息。
  • 没问题,很多成员有时对位运算符感到困惑,包括我自己,只要确保没有混淆,还有很棒的代码块 :) +1
【解决方案2】:
$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

【讨论】:

    【解决方案3】:
    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
        )
    
    )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-23
      • 1970-01-01
      相关资源
      最近更新 更多