搜索

首页  >  问答  >  正文

php - 一个分拆数组的算法

现有如下需求:首先有个数组$arr = array(1 => 12, 2 => 23);现在要将该数组进行拆分,生成一个新的数组,新数组的个数如下:

$newArr = array(
    array(2, 7),
    array(2, 7),
    array(2, 9),
    array(1, 3),
    array(1, 9),
)

必须满足一下条件:
1:新数组必须是有5项;
2:必须按照原有数组中最大的值来进行先拆分,然后次大值。。。,至于每项要拆分成多少个,自行决定,
3:拆分后的数组二维中的第一个值为原有的key,值为拆分后的数值,二维中第一个值相同的加起来必须等于原来数组的key对应的值。

PHPzPHPz2902 天前497

全部回复(1)我来回复

  • 大家讲道理

    大家讲道理2017-04-10 15:11:59

    余兴节目。我就直接粘答案了。技巧:

    1. 想象成一个线段,在上边随机选若干个点将其切断。统计每一段的长度相加起来就必然是正确的和值。
    2. 题目不禁止结果中出现0,所以选点的时候允许重复。
    3. 和值为负的时候,翻转成正的处理。
    <?php
    header("Content-Type: text/plain; ");
    
    $input = [1 => 12, 2 => 23];
    $input = [1 => 0, 2 => 0];
    define("TOTAL_SEGMENTS", 5);
    
    $input_sorted = $input; 
    asort($input_sorted);
    
    $segment_counts = [];
    $segment_counts[0] = mt_rand(1, TOTAL_SEGMENTS - 1);
    $segment_counts[1] = TOTAL_SEGMENTS - $segment_counts[0];
    
    $result = [];
    for ($i_slice = 0; $i_slice < 2; $i_slice++) {
        $input_record  = array_slice($input_sorted, -($i_slice + 1), 1, true);
        $record_key    = array_keys($input_record)[0];
        $target_sum    = array_values($input_record)[0];
        $segment_count = $segment_counts[$i_slice];
    
        if ($target_sum < 0) {
            $negative_sum = true;
            $target_sum = -$target_sum; 
        } else { 
            $negative_sum = false;
        }
    
        $positions = [0, $target_sum];
        while (count($positions) < ($segment_count + 1)) {
            $t = mt_rand(0, $target_sum);
            array_push($positions, $t); //不禁止出现0的时候无需判重(如果禁止出现0这个题就麻烦了)
        }
        sort($positions);
    
        for ($i = 0; $i < $segment_count; $i++) {
            $value = $positions[$i + 1] - $positions[$i];
            if ($negative_sum) { $value = -$value; }
            array_push($result, [$record_key, $value]);
        }
    }
    
    foreach ($result as $line) { printf("array(%d, %d), \n", $line[0], $line[1]); }
    

    回复
    0
  • 取消回复