php實現排列組合
一、總結
1、回溯:回溯的函數參數有些生疏了,記錄遞歸的位置(pos或step),還要有東西(vis數組)來記錄這個是否已經被訪問
2、php全局變量的使用 :外部定義的普通變量,函數內部定義global
二、代碼
需求:php實現排列組合
代碼一:
1 /** 2 * 排列組合 3 * 采用二進制方法進行組合的選擇,如表示5選3時,只需有3位為1就可以了,所以可得到的組合是 01101 11100 00111 10011 01110等10種組合 4 * 5 * @param 需要排列的數組 $arr 6 * @param 最小個數 $min_size 7 * @return 滿足條件的新數組組合 8 */ 9 function pl($arr,$size=5) { 10 $len = count($arr); 11 $max = pow(2,$len); 12 $min = pow(2,$size)-1; 13 $r_arr = array(); 14 for ($i=$min; $i<$max; $i++){ 15 $count = 0; 16 $t_arr = array(); 17 for ($j=0; $j<$len; $j++){ 18 $a = pow(2, $j); 19 $t = $i&$a; 20 if($t == $a){ 21 $t_arr[] = $arr[$j]; 22 $count++; 23 } 24 } 25 if($count == $size){ 26 $r_arr[] = $t_arr; 27 } 28 } 29 return $r_arr; 30 } 31 $pl = pl(array(1,2,3,4,5,6,7),5); 32 var_dump($pl);
代碼二:
1 <?php 2 namespace app\index\controller; 3 4 use app\index\controller\Base; 5 6 class Exercise extends Base 7 { 8 public function index() 9 { 10 // return view('insert_array'); 11 $this->plzhDemo(); 12 } 13 14 /** 15 * php實現排列組合 16 * 參數:傳入數組 排列組合所取的位數 vis數組 ans數據用來記錄每次的結果 17 * 算法;遞歸(回溯) 18 * 返回值:返回排列組合結果數組 19 * @return [type] [description] 20 */ 21 private $count1=0; 22 public function plzh($arr,$n,$pos,$vis,$ans){ 23 //1、遞歸返回條件:位數夠了就可以返回了 24 if($pos>$n-1){ 25 global $count1; 26 $count1++; 27 dump($ans); 28 }else{ 29 $len=count($arr); 30 for ($i=0; $i < $len; $i++) { 31 if($vis[$i]==0){//沒取 32 $ans[$pos]=$arr[$i]; 33 $vis[$i]=1; 34 $this->plzh($arr,$n,$pos+1,$vis,$ans); 35 $vis[$i]=0; 36 } 37 } 38 } 39 //2、遞歸里面的算法(一位一位的來取)取一位之后,把這一位的數標記置為已經取了,然后取后面的位的時候從沒有取的數里面取,所以需要標記數組 40 //2.1、 從未取的數里面依次取一位就好 41 42 } 43 public function plzhDemo(){ 44 $arr=array(1,2,3,4,5,6,7); 45 $n=5; 46 $vis=array(); 47 for ($i=0; $i <=count($arr) ; $i++) { 48 $vis[$i]=0; 49 } 50 $ans=array(); 51 $this->plzh($arr,$n,0,$vis,$ans); 52 global $count1; 53 dump($count1); 54 } 55 56 }
截圖: