【问题标题】:How to create a sub-set array如何创建子集数组
【发布时间】:2015-03-14 02:05:29
【问题描述】:

例如给定一个数组:

$array = array(1,2,3);

如何创建一个包含所有可能子集的数组:

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

【问题讨论】:

    标签: php arrays subset


    【解决方案1】:

    我认为这是一个很好的问题 - 查找集合的子集有多种方法 我更喜欢使用二进制方法:

    对于给定的一组n,有n^2 suset。您可以从 0 到 2^n 以二进制计数,并将二进制数解释为相应的子集。请注意,这种方法需要一个具有足够位数的二进制数来表示整个集合,因此我们需要填充二进制表示。

    更多阅读binary-subsets

    我的实现

    $arr = array(1,2,3);
    $res = subsets($arr);
    
    function subsets($arr,$sort = true,$include_empty = false,$include_full = false) {
       $length = count($arr);
       $res = array();
       if (!$length && $include_full) return $res;
       for ($i = 0; $i<pow(2, $length); $i++) {
           $set = array();
           $bin = str_split(str_pad(decbin($i), $length, "0", STR_PAD_LEFT));
           $binLen = count($bin);
           for ($j = 0; $j < $binLen; $j++)
               if ($bin[$j] === "1") $set[] = $arr[$j];
           $res[] = $set;
        }
        foreach($res as $k => $val)
           if (!count($val) && !$include_empty) unset($res[$k]);
           elseif (count($val) === $length && !$include_full) unset($res[$k]);
        function cmp($a, $b){ return (count($a) - count($b)); }
        if ($sort) usort($res, 'cmp');
        return $res;
    }
    
    //Output Results:
    foreach ($res as $key => $data) {
       echo $key." -> [".(implode(',',$data))."]\r";
    }
    /*
    0 -> [1]
    1 -> [3]
    2 -> [2]
    3 -> [1,2]
    4 -> [2,3]
    5 -> [1,3]
    */
    

    如您所见,该函数处理输入数组,您可以选择是否在结果中包含空集和完整集。

    您应该知道迭代次数正在急剧增加:

    不删除空集或完整集:

    n*(2^n)
    

    删除:

    (2^n) + n*(2^n)
    

    删除和排序(最坏情况):

    (2^n) + n*(2^n) + n^2
    

    假设我们有一个包含 9 个值的输入数组:

    (2^9)*9 = 4608;
    
    (2^9) + 9*(2^9) = 5120;
    
    (2^9) + 9*(2^9) + 9^2 = 5201;
    

    这是我所知道的最快的方式。

    注意: 该函数需要一个唯一的数组 - 您可以确保您的数组是唯一的:

    $arr = array_unique ($arr);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-02-19
      • 1970-01-01
      • 1970-01-01
      • 2022-01-20
      • 1970-01-01
      • 1970-01-01
      • 2017-02-04
      相关资源
      最近更新 更多