拆分数组但每个数组的总和不超过最大值,否则推送到下一个数组索引

时间:2016-10-06 05:28:03

标签: php arrays

我有两个数组,数组1是一个施主数组,它有一系列值(不一定是我的例子中的相等值)。数组2是期望的结果,并且将存储一系列具有来自数组1的值的子数组,其中每个子数组的总和不会超过25.如果确实如此,超出部分将被推送到数组2中的下一个索引,其中规则将是也适用。

捐赠者阵列(阵列1):

$a1=array(10,10,10,10,10,10,10,10,10,10);

所需的输出(数组2):

Array
(
    [0] => 10,10,5
    [1] => 5,10,10
    [2] => 10,10,5
    [3] => 5,10,10
)

这里是我尝试过的代码,但是出现错误:

  

注意:未定义的偏移量: 10 ...等。

$a1=array(10,10,10,10,10,10,10,10,10,10);
$a2=array();
$count=count($a1);

for($i=0;$i<$count;$i++){
    $a2count=array_sum($a2);

    if($a2count>25){
        $i=$i+1;
        $a2[$i]=$a1[$i];
    }
    else{
        $a2[$i]=$a1[$i];
    }
}

print_r($a2);

我不知道要实现什么逻辑并获得我正在寻找的结果。

4 个答案:

答案 0 :(得分:2)

也许这样的事情对你有用。我会注意到它不仅仅是一个复制粘贴的答案。也许有人会对它有所了解以便在将来改进它:

function slitArray($a1,$num = 25)
    {
        # Used to store the difference when the value exceeds the max
        $store  =   0;
        # Storage container that will be built using sums/diffs
        $new    =   array();
        # Loop through the main array
        foreach($a1 as $value) {
            # If the last key/value pair in our return array is an array
            if(is_array(end($new)))
                # Add up the values in that array
                $sum    =   array_sum(current($new));
            else
                # If not array, no values have been stored yet
                $sum    =   0;
            # This just gets the last key
            $count      =   (count($new)-1);
            # Assign last key
            $i          =   ($count <= 0)? 0 : $count;
            # If the sum of the current storage array plus the value
            # of the current array is greater than our max value
            if(($sum + $value) > $num) {
                # Take max and remove the current total of storage array
                $use            =   ($num-$sum);
                # Take what's left and remove it from the current value
                $store          =   ($value-$use);
                # If the current stored value (the value we want to push to
                # the next storage k/v pair) is more than the max allowed
                if($store > $num) {
                    # Takes a value, checks if it's greater than max,
                    # and if it is, breaks the value up by max as a divider
                    $divide =   function($store,$num)
                        {
                            if($store > $num) {
                                $count  =   ceil($store/$num);
                                for($i=0; $i<$count; $i++) {
                                    $new[]  =   ($store > $num)? $num : $store;
                                    $store  -=  $num;
                                }

                                return $new;
                            }
                            else
                                return array($store);
                        };
                    # This should either be an array with 1 or more values
                    $forward    =   $divide($store,$num);
                    # Do a look forward and add this excess array into our
                    # current storage array
                    $a          =   $i; 
                    foreach($forward as $aVal) {
                        $new[$a+=1][]   =   $aVal;
                    }
                }
                # If the store value is less than our max value, just add
                # it to the next key in this storage array
                else {
                    $new[$i+1][]    =   $store;
                    # Reset the storage back to 0, just incase
                    $store          =   0;
                }
            }
            # Set the current "use" value as the current value in our
            # from-array. Since it doesn't exceed the max, it just gets
            # added to the storage array
            else
                $use    =   $value;
            # Sometimes the math makes $use 0, keep that out of the
            # storage array. The $use value is the current value to add at
            # the time of iteration. Previous storage values are added as
            # future-keys
            if($use > 0)
                $new[$i][]      =   $use;
        }
        # Return the final assembled array
        return $new;
    }

# To use, add array into function
$a1 =   array(10,10,10,10,10,10,10,10,10,10);
# to split using different max value, just add it to second arg
# example: slitArray($a1,20);
print_r(slitArray($a1));

给你:

Array
(
    [0] => Array
        (
            [0] => 10
            [1] => 10
            [2] => 5
        )

    [1] => Array
        (
            [0] => 5
            [1] => 10
            [2] => 10
        )

    [2] => Array
        (
            [0] => 10
            [1] => 10
            [2] => 5
        )

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

数组输入:

$a1 =   array(23,2,71,23,50,2,3,4,1,2,50,75);

给你:

Array
(
    [0] => Array
        (
            [0] => 23
            [1] => 2
        )

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

    [2] => Array
        (
            [0] => 25
        )

    [3] => Array
        (
            [0] => 21
            [1] => 4
        )

    [4] => Array
        (
            [0] => 19
            [1] => 6
        )

    [5] => Array
        (
            [0] => 25
        )

    [6] => Array
        (
            [0] => 19
            [1] => 2
            [2] => 3
            [3] => 1
        )

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

    [8] => Array
        (
            [0] => 25
        )

    [9] => Array
        (
            [0] => 6
            [1] => 19
        )

    [10] => Array
        (
            [0] => 25
        )

    [11] => Array
        (
            [0] => 25
        )

    [12] => Array
        (
            [0] => 6
        )

)

答案 1 :(得分:1)

你走了:逻辑并不那么难。希望它有所帮助。

   <?php 

   $a1=array(10,10,10,10,10,10,10,10,10,10);

   $a2 = [];
   $a3 = [];

   $m = 0;

   for($i = 0; $i < count($a1); ++$i){      

        $m += $a1[$i];

        if($m > 25){

           $n = $m % 25;

           if(array_sum($a2) != 25){

               $a2[] = $n;

           }


           $a3[] = implode(',', $a2);       

           $a2 = []; 

           $m = $n;

           $a2[] = $n;


         } else{

           $a2[] = $a1[$i];

         }


   }

   $a3[] = implode(',', $a2);

   print_r($a3);

   ?>

答案 2 :(得分:0)

让我帮你使用Pseudocode:

ar1 = {10,10,10,20,40,[0]=>1,[0]=>3,[0]=>4};

ar2 = new array (ar.length) \\ worst case

int c = 0; \\current

foreach (ar1 as $value){

ar2 [c]+=ar1[i];

if (ar2 [c]>25){ c++;}

}

代码背后的逻辑:

Add ar1[i] to当前ar2值的值,直到它通过your limit(在这种情况下为25)。 If它超出了你的边界,than移动到目标数组中的next值。 worst case将是每个值超过25,因此它将是原始数组的exact copy

这里是php代码:

$ar1=array(10,10,10,10,10,10,10,10,10,10);

$ar2 = array(0,0,0,0,0,0,0,0,0,0);

$c = 0;

foreach( $ar1 as $key => $value ){

    $ar2[$c]=$value+$ar2[$c];

    if ($ar2[$c]>25){$c++;}

}

答案 3 :(得分:0)

此问题的最终代码

<?php 
function slitArray($a1,$num = 25)
{
  $store  =   0;
  $new    =   array();

  foreach($a1 as $value) {

    if(is_array(end($new)))
      $sum    =   array_sum(current($new));
    else
      $sum    =   0;

    $count      =   (count($new)-1);
    $i          =   ($count <= 0)? 0 : $count;

    if(($sum + $value) > $num) {
      $use            =   ($num-$sum);
      $store          =   ($value-$use);
      if($store > $num) {
    $divide =   function($store,$num)
      {
        if($store > $num) {
          $count  =   ceil($store/$num);
          for($i=0; $i<$count; $i++) {
        $new[]  =   ($store > $num)? $num : $store;
        $store  -=  $num;
          }

          return $new;
        }
        else
          return array($store);
      };

    $forward    =   $divide($store,$num);
    $a          =   $i; 
    foreach($forward as $aVal) {
      $new[$a+=1][]   =   $aVal;
    }
      }
      else {
    $new[$i+1][]    =   $store;
    $store          =   0;
      }
    }
    else
      $use    =   $value;

    if($use > 0)
      $new[$i][]      =   $use;
  }

  return $new;
}

$a1 = array(10,20,30,40,50,60);

$arr=slitArray($a1);

print_r($arr);

?>