【问题标题】:Split array but sum of each array not to exceed a max value else push to next array index拆分数组,但每个数组的总和不超过最大值,否则推送到下一个数组索引
【发布时间】:2017-02-14 17:40:09
【问题描述】:

我有两个数组,数组 1 是一个供体数组,它具有一系列值(不一定像我的示例中那样相等)。数组 2 是所需的结果,它将存储一系列子数组,其中每个子数组的总和不超过 25,其中每个子数组的总和不超过 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);

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

【问题讨论】:

    标签: php arrays


    【解决方案1】:

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

    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
            )
    
    )
    

    【讨论】:

    • 是的兄弟,这也有效,我会更新我的答案谢谢兄弟
    • 兄弟,如果我给出的值小于 25 意味着工作完美。但是大于 25 是在最后添加数组,只需使用 array(23,2,2,23,50,50); 进行检查
    【解决方案2】:

    给你:逻辑并不难。希望对您有所帮助。

       <?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);
    
       ?>
    

    【讨论】:

    • 使用array_push, array_push($a2, $n) 等于$a2[]=$n see 的否决票
    • @Kinshuk Lahiri 如果我给数组 1 的值超过 25,它就会消失,只需使用 array(23,2,2,23,50,50)
    • 余数为0的情况下需要添加if条件。if($n == 0){ $n = $m / $constant; $n = $m / $n; }
    • @Kinshuk Lahiri 感谢您的努力。它的工作但最后一个索引值没有在 array2 检查中拆分 array(50,50,50) 只有前两个元素拆分
    • @Vivil 是的,我知道。这就是我还没有在代码中更新它的原因。会检查的。目前正在工作。
    【解决方案3】:

    本题的最终代码

    <?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);
    
    ?>
    

    【讨论】:

      【解决方案4】:

      让我用伪代码帮你一点:

      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++;}
      
      }
      

      代码背后的逻辑:

      Addar1[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++;}
      
      }
      

      【讨论】:

      • 我在等@TheRealVira
      • @Vivil 完成了 - 似乎比其他的短一些 - 我还认为你想要得到 ar1 数组的数字总和,所以你开始吧!希望它仍然有帮助:)
      • 它只添加我想要插入的索引值。如果达到25,它应该分成两部分。请查看@Rasclatt 答案
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-12
      • 1970-01-01
      • 2015-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-04
      相关资源
      最近更新 更多