排列组合(包含所有组合可能和指定元素个数的组合)

声明:本文是在参考资料后所做的总结,对其中的部分优质内容也许会有“复制粘贴”操作。由于水平有限,不足之处在所难免,欢迎大家留言指正

问题分析

当元素个数少时...

  元素 组合方式
F(1) A (A)
F(2) A,B (B)(BA)(A)
F(3) A,B,C (C)(CB、CBA、CA)(B、BA、A)
F(4) A,B,C,D (D)(DC、DCB、DCBA、DCA、DB、DBA、DA)(C、CB、CBA、CA、B、BA、A)
F(n) ... ...  

由上表可以得出,

N 个元素的所有组合方式 = 第 N 个元素 + 第 N 个元素与 N-1 个元素所有组合方式的两两组合 + N-1 个元素所有组合。

如果用 F(n) 表示 n 个元素的所有组合,an 表示第 n 个元素,那么,

F(n) = an + an.F(n-1) + F(n-1) (n>1)

代码(PHP):

// 输出所有组合
function recursion_combination(array $arr){
    $result = array();
    $temp = $arr;
    if (!$temp || count($temp) == 0) {
        return;
    }elseif(count($temp) == 1){
        $result = $temp;
    }else{
        $str = $temp[0];
        array_push($result,array_shift($temp));
        $substr = recursion_combination($temp);
        foreach ($substr as $value) {
            array_push($result,$str.$value);
        }
        foreach ($substr as $value) {
            array_push($result,$value);
        }
    }
    return $result;
}

// 输出指定元素个数的组合
function combination_specified(array $arr,$num){
    $result = array();
    $temp = $arr;
    foreach ($temp as $value) {
        if (strlen($value) == $num) {
            array_push($result,$value);
        }
    }
    return $result;
}

// 函数调用
$arr = array("A","B","C","D");
$allResult = recursion_combination($arr);
$specifiedNums = combination_specified(recursion_combination($arr),2);

echo "所有组合:";
foreach ($allResult as $value) {
	echo $value."、";
}
echo "
"."指定元素个数的组合:"; foreach ($specifiedNums as $value) { echo $value."、"; }

结果输出

所有组合:A、AB、ABC、ABCD、ABD、AC、ACD、AD、B、BC、BCD、BD、C、CD、D、
指定元素个数的组合:AB、AC、AD、BC、BD、CD、

结果校验:

排列组合(包含所有组合可能和指定元素个数的组合)_第1张图片

方法改进:

如果给出的元素中,不都是单个字符 ,例如 {"A","12","#$&"}。那么使用上述方法不能得出指定元素个数的组合。

思路说明:

将组合结果存放在一个二维数组里面,结构如下:

$result = Array
(
    [0] => Array
        (
            [0] => (组合结果)
            [1] => (组合元素1)
            [2] => (组合元素1)
            ... ...
        )

   ... ...

)

 那么,

获取所有组合时,只要输出 $result[$i][0] 即可;

获取 k 个元素的组合,判断 $result[$i] 的长度,如果 count($result[$i]) == k+1,输出 $result[$i][0]。

代码(PHP):

// 所有组合
function recursion_combination_plus(array &$arr){
    $result = array();
    $temp = $arr;
    if (!$temp || count($temp) == 0) {
        return;
    }elseif(count($temp) == 1){
        array_push($result,array(array_shift($temp)));
        array_push($result[0],$result[0][0]);
    }else{
        $str = $temp[0];
        array_push($result,array(array_shift($temp)));
        array_push($result[0],$str);
        $substr = recursion_combination_plus($temp);
        foreach ($substr as $value) {
            $data1 = array();
            array_push($data1,$str);
            foreach ($value as $key => $sonValue) {
                if($key == 0){
                    array_unshift($data1,$str.$sonValue);
                }else{
                    array_push($data1,$sonValue);
                }
            }
            array_push($result,$data1);
        }
        foreach ($substr as $value) {
            array_push($result,$value);
        }
    }
    return $result;
}

// 指定元素个数组合
function combination_specified_plus(array $arr,$num){
    $result = array();
    foreach ($arr as $value) {
        if (count($value) == $num+1) {
            array_push($result,$value[0]);
        }
    }
    return $result;
}

$arr = array("A","12","#%$");
$allResult = recursion_combination_plus($arr);
$specifiedNums = combination_specified_plus(recursion_combination_plus($arr),2);
echo "所有组合:";
foreach ($allResult as $value) {
	echo $value[0]." , ";
}
echo "
"."指定元素个数的组合:"; foreach ($specifiedNums as $value) { echo $value." , "; }

运行结果:

所有组合:A , A12 , A12#%$ , A#%$ , 12 , 12#%$ , #%$ , 
指定元素个数的组合:A12 , A#%$ , 12#%$ ,

你可能感兴趣的:(算法)