算法描述:如果用P表示n個元素的全排列,而Pi表示n個元素中不包含元素i的全排列,(i)Pi表示在排列Pi前面加上前綴i的排列,那么n個元素的全排列可遞歸定義為:
① 如果n=1,則排列P只有一個元素i;
② 如果n>1,則全排列P由排列(i)Pi構成;
根據定義,可以看出如果已經生成(k-1)個元素的排列Pi,那么k個元素的排列可以在每個Pi前面加上元素i而生成。
1、
1 <?php 2 function rank($base, $temp=null) 3 { 4 $len = strlen($base); 5 if($len <= 1) 6 { 7 echo $temp.$base.'<br/>'; 8 } 9 else 10 { 11 for($i=0; $i< $len; ++$i) 12 { 13 rank(substr($base, 0, $i).substr($base, $i+1, $len-$i-1), $temp.$base[$i]); 14 } 15 } 16 } 17 rank('123');
不過,這樣的算法有個問題:若是存在相同的元素,則全排列有重復。例如'122'的全排列只有三種情況:'122'、'212'、'221';上面方法卻有重復。
2、在上面算法的基礎上價格判重操作即可
1 <?php 2 function fsRank($base, $temp=null) 3 { 4 static $ret = array(); 5 $len = strlen($base); 6 if($len <= 1) 7 { 8 //echo $temp.$base.'<br/>'; 9 $ret[] = $temp.$base; 10 } 11 else 12 { 13 for($i=0; $i< $len; ++$i) 14 { 15 $had_flag = false; 16 for($j=0; $j<$i; ++$j) 17 { 18 if($base[$i] == $base[$j]) 19 { 20 $had_flag = true; 21 break; 22 } 23 } 24 if($had_flag) 25 { 26 continue; 27 } 28 fsRank(substr($base, 0, $i).substr($base, $i+1, $len-$i-1), $temp.$base[$i]); 29 } 30 } 31 return $ret; 32 } 33 print '<pre>'; 34 print_r(fsRank('122')); 35 print '</pre>'; 36 ?>