X元素组合成1,2,3,4 ...... X子子阵列

时间:2015-06-06 02:53:56

标签: php powerset

我有一个如下所示的数组:[0,1,2,3,4,5,...]

我需要一个能给我一个这样的数组的函数:

[
[[0, 1, 2, 3, 4, 5]],  
[[0, 1, 2, 3, 4], [ 5 ]], 
[[0, 1, 2, 3], [ 4, 5 ]], 
[[0, 1, 2], [ 3, 4, 5 ]], 
...
[[0, 1, 2], [ 3, 4 ], [ 5 ]],
...
[[ 0 ], [ 1 ], [ 2 ], [ 3 ], [ 4 ], [ 5 ]]
]

当然这个输出只有6个元素 如果查看输出数组的第2行,第3行和第4行,它可以组合成2个子数组。
如果查看输出数组的第6行,它将变为3个子数组 在最后一行中,每个元素应该在其自己的子数组中单独存在。

我在this page上看到了这些例子,我尝试了这些函数,但是我的函数有点不同,因为元素的顺序需要得到尊重。这意味着无论括号在哪里, 你应该在每一行看到1 2 3 4 5 6。

此外,前面提到的页面中的函数将给我一个包含所有子数组的数组:
[[x,x],[x],[x],[xxx]]我不能用它。

我需要的是这种格式:

[  
[ [ 1 , 2 , 3 ] ] ,  
[ [ 1 , 2 ] , [ 3 ] ] ,  
[ [ 1 ] , [ 2 , 3 ] ] ,  
[ [ 1 ] , [ 2 ] , [ 3 ] ]  
]

我是初学者,请有人给我一个如何做到这一点的暗示!

2 个答案:

答案 0 :(得分:0)

我刚刚开发了一种非常特殊的方法来实现您正在寻找的东西(使用二进制标签遍历二叉树!我不知道它是否已经存在!!)它非常快且不使用递归:)

<?php
function getSpecialSubsets($in) {
    $in = array_reverse($in);
    $n = count($in);

    $out = array();
    // for every possible route
    for($i = 0; $i<pow(2, $n-1); $i++) {
        $out[$i] = array(array());

        // for every value in the input array
        for($j=$n-1; $j>=0; $j--) {
            $val = $in[$j];
            if(($i >> $j) & 1)
                $out[$i][] = array($val);
            else $out[$i][count($out[$i])-1][] = $val;
        }
    }

    return $out;
}

$subsets = getSpecialSubsets([1, 2, 3, 4]);

// for demonstration purposes only!!
echo "<pre>";
echo preg_replace('~\]\],~', "]],\n", json_encode($subsets));
echo "</pre>";
?>

答案 1 :(得分:0)

这花了我几个小时的时间来制作!!

你是对的,your question被错误地设置为重复。但是,在那个问题中你想要的是所有 Partitions of the set而不是你想要的here(这里你想要一个子集在任何一种情况下,您可以使用以下内容来获得所需的输出,只需将标记行中所需函数的名称替换为您想要的任何内容(我的意思是您也可以将其更改为getSpecialSubsets()提出above

当你打电话告诉时,getVerySpecialSubsets()所需的主要功能也有$level_min$level_max的有利论据:)

<?php
function allPermutations($InArray, $InProcessedArray = array())
{
    $ReturnArray = array();
    foreach($InArray as $Key=>$value)
    {
        $CopyArray = $InProcessedArray;
        $CopyArray[$Key] = $value;
        $TempArray = array_diff_key($InArray, $CopyArray);

        if (count($TempArray) == 0)
            $ReturnArray[] = array_values($CopyArray);
        else
            $ReturnArray = array_merge($ReturnArray, allPermutations($TempArray, $CopyArray));
    }
    return $ReturnArray;
}

function powerSet($in,$minLength = 1) { 
   $count = count($in); 
   $members = pow(2,$count); 
   $return = array(); 
   for ($i = 0; $i < $members; $i++) { 
      $b = sprintf("%0".$count."b",$i); 
      $out = array(); 
      for ($j = 0; $j < $count; $j++) { 
         if ($b{$j} == '1') $out[] = $in[$j]; 
      } 
      if (count($out) >= $minLength) { 
         $return[] = $out; 
      } 
   } 
   return $return; 
}

function getAllPartitionsOfSet($in) {
    $arr = powerSet(powerSet($in));

    $out = array();
    foreach($arr as $combination) {
        $a = array();
        foreach($combination as $_arr)
            foreach($_arr as $v)
                $a[] = $v;

        // check if $a has duplicates
        // (i.e: the intersection of subsets in $combination is void)
        if(count($a) !== count(array_unique($a)))
            continue;

        // check if there's no difference between $a and $in.
        // (i.e: the union of subsets in $combination is equal to $a)
        if(!empty(array_diff($a, $in)) || !empty(array_diff($in, $a)))
            continue;

        $out[] = $combination;
    }
    return $out;
}

function getVerySpecialSubsets($_in, $level_min = 1, $level_max = 0) {
    $in = array_reverse($_in);
    $n = count($in);

    $level_min = $level_min>0 ? $level_min : 1;
    $level_max = $level_max>0 ? $level_max : $n;

    $allPartitions = getAllPartitionsOfSet($_in); //* marked!
    $out = array();

    foreach($allPartitions as $partition) {
        $levels_count = count($partition);
        if($levels_count>$level_max || $levels_count<$level_min)
            continue;

        // add the permutations of the arrays
        for($i=0; $i<count($partition); $i++) {
            $per = allPermutations($partition[$i]);
            if(count($per)==1)
                continue;

            // combine the permutation with the rest of array
            $first_item = true;
            foreach($per as $_per) {
                $arr = array();
                for($j=0; $j<count($partition); $j++)
                    $arr[] = ($j==$i) ? $_per : $partition[$j];
                $out[] = $arr;
            }
        }
    }

    // last singles
    if($n<=$level_max && $n>=$level_min) {
        $arr_last = array();
        for($k=count($in)-1; $k>=0; $k--)
            $arr_last[] = array($in[$k]);
        $out[] = $arr_last;
    }

    return array_values(array_unique($out, SORT_REGULAR));
}

$subsets = getVerySpecialSubsets([0, 1, 2]);

// for demonstration purposes only!!
echo '<pre>';
echo preg_replace('~\]\],~', "]],\n", json_encode($subsets));
echo '</pre>';
?>