获得符合特定范围标准的可能组合(大小为N)

时间:2015-10-02 16:13:24

标签: php arrays algorithm range combinations

// Input array
$arr = [
    'A' => '9-11',
    'B' => '9-12',
    'C' => '12-14',
    'D' => '13-14',
    'E' => '15-16',
    'F' => '15-16',
    'G' => '13-14',
    'H' => '14-16'
];

// ranges
$start = 9;
$end = 16;

// Desired outputs:
A + C + E (9-11, 12-14, 15-16)
A + C + F (9-11, 12-14, 15-16)
A + C + H (9-11, 12-14, 14-16)

B + D + E (9-12, 13-14, 15-16)
B + G + F (9-12, 13-14, 15-16)
B + G + H (9-12, 13-14, 14-16)

所以这意味着,每个组合必须从9开始(我们$start = 9)并尝试最多16个(即$end = 16 IF AVAILABLE),每个n个元素组合(这里,n = 3)。

我在网上搜索了很多问题,并尝试了一些自己的方法。但不幸的是,他们甚至没有得到更接近解决方案的标题。我工作的问题与上面的例子和复杂的不同。

1 个答案:

答案 0 :(得分:1)

您需要在多次迭代中执行此操作:

  1. 创建一个递归函数,简单地从给定数组中构建大小为n的组合 (作为预处理步骤,您希望将9-11更改为[9,11],以便以后轻松检查范围,例如>= $range[0]为最小值... <= $range[1]为最大值)
  2. 然后添加条件以过滤掉不以$start开头的组合。
  3. 然后添加条件以过滤掉那些不以$end
  4. 结尾的条件

    编辑:一个好的开始可能是:

    function appendElements($elements, & $dst) {
        foreach ($elements as $ele) $dst[] = $ele;
    }
    
    function buildTouples($map, $start, $end, $size, $currentSize, $touplesToExtend) {
        if ($currentSize == $size) return $touplesToExtend;
        if ($map === []) return [];
    
        $allTouples = [];
        foreach ($map as $key => $range) {
            unset($map[$key]);
            foreach ($touplesToExtend as $toupleToExtend) {
                $toupleToExtend[] = $key;
                $newTouples = 
                   buildTouples($map, $start, $end, $size, $currentSize+1, [$toupleToExtend]);
                appendElements($newTouples, $allTouples);
            }
        }
        return $allTouples;
    }
    

    用作:

    $map = [
        'A' => [9,11],
        'B' => [9,12],
        'C' => [12,14],
        'D' => [13,14],
        'E' => [15,16],
        'F' => [15,16],
        'G' => [13,14],
        'H' => [14,16]
    ];
    $start = 9;
    $end = 16;
    $size = 3;
    $touples = buildTouples($map, $start, $end, $size, 0, [[]]);
    
    foreach ($touples as $touple) {
        foreach ($touple as $val) echo $val;
        echo ', ';
    }
    

    输出:

      

    ABC,ABD,ABE,ABF,ABG,ABH,ACD,ACE,ACF,ACG,ACH,ADE,ADF,ADG,ADH,AEF,AEG,AEH,AFG,AFH,AGH,BCD,BCE,BCF ,BCG,BCH,BDE,BDF,BDG,BDH,BEF,BEG,BEH,BFG,BFH,BGH,CDE,CDF,CDG,CDH,CEF,CEG,CEH,CFG,CFH,CGH,DEF,DEG,DEH ,DFG,DFH,DGH,EFG,EFH,EGH,FGH,