组合算法分析
<?php
class args
{
var $arr = array('a', 'b',"c",'d','e');//选取的原始数组
var $n = 5;//数组元素总数
var $str = "";//当前选出的结果(临时数据)
var $a = array();//存放组合完成的结果
function __construct()
{
$this->c();
}
function c(){
for($i=0;$i<$this->n;$i++){//执行的第一层
$this->str .= $this->arr[$i];//将第一项选出来
for($j=$i+1;$j<$this->n;$j++){//从第一项开始向后查找第二项
$this->str .= $this->arr[$j];//将第一项、第二项组合
for($k=$j+1;$k<$this->n;$k++){
$this->str .= $this->arr[$k];//将所有项组合
$this->a[] = $this->str;//组合结果存放到数组
if($k>=$this->n-1){//如果第三层移动到最后
$this->str =$this->arr[$i];//清空第二层之前选出的项(进入第二层的下面操作)
}else{
$this->str=$this->arr[$i].$this->arr[$j];
//没有移动到最后,前两次选出的项继续与剩下的匹配(进入第三层的下次循环)
}
}
if($j>=$this->n-1){//如果第二层移动到最后
$this->str ="";//清空之前选出的项(进入第一层的下一次循环)
}else{
$this->str=$this->arr[$i];
//没有移动到最后,第一次选出的项继续与剩下的匹配(进入第二层的下次循环)
}
}
}
}
}
$a = new args();
var_dump($a->a);//打印数组a
难点在于,将不同层之间的判断,统一化。将不同层之间的组合值进行合理的整理。
整理成递归法后的结果:
<?php
class args
{
var $arr = array();//选取的原始数组
var $n = 0;//数组元素总数
var $r = 0;//选择组合的个数
var $a = array();//存放最终结果的数组
function __construct()
{
$this->arr = func_get_arg(0);//获取要被选择的数组
$this->r = func_get_arg(1);//获取要从数组中选取的个数
$this->n = count($this->arr);//计算原始数组的长度
$this->c();
}
/**
* n 当前层被固定项的位置
* str 执行到当前层已经组合完的字符串
*
* 组合完成一定发生在最后一层
* 当前层进行下次循环前一定要移除当前层已被组合的项
*/
function c($n=0,$str=""){
for($i=$n;$i<$this->n;$i++){
$str .= $this->arr[$i];//将当前层的项加入到字符串中
if(strlen($str) >= $this->r){//验证是否组合完成(防止额外重复一次循环)
$this->a[] = $str;//组合结果存放到数组
}else{
$this->c($i+1,$str);//如果仍未组合完成 执行下一层
}
$str = substr($str,0,-1);//移除当前层已经组合进来的项
}
}
}
$a1 = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z');
$a2 = array('a', 'b',"c",'d','e','f');
$a = new args($a2,2);
var_dump($a->a);
运行结果:
array(15) {
[0] => string(2) "ab"
[1] => string(2) "ac"
[2] => string(2) "ad"
[3] => string(2) "ae"
[4] => string(2) "af"
[5] => string(2) "bc"
[6] => string(2) "bd"
[7] => string(2) "be"
[8] => string(2) "bf"
[9] => string(2) "cd"
[10] => string(2) "ce"
[11] => string(2) "cf"
[12] => string(2) "de"
[13] => string(2) "df"
[14] => string(2) "ef"
}
成功实现!