A time before a party chatting to a problem, is to give you a row of arrays, such as 1,2,3,4,5, how to efficiently get all the permutations of the above series, happened to be nothing, studied a bit, at first thought is a very simple problem, began to write code directly, and then found how the cycle is not ideal, Basically have some unnecessary consumption, Baidu see a good algorithm, dictionary order method, by the way to learn, and then record it.
Picking an algorithm idea:
Set P is a full arrangement of [1,n].
P=p1p2 ... Pn=p1p2 ... Pj-1pjpj+1 ... Pk-1pkpk+1 ... Pn, j=max{i| Pi<pi+1}, k=max{i| PI>PJ}, swap pj,pk, will pj+1 ... Pk-1pjpk+1 ... PN Flip, P ' = p1p2 ... PJ-1PKPN ... Pk+1pjpk-1 ... Pj+1 is the next
example: The next permutation of 839647521.
Starting from the right, Find the first number 4 smaller than the right (because 4<7, and 7>5>2>1), and then from the far right, find 4 to the right than 4 of the number 5 (because 4>2>1 and 4<5), Exchange 4, 5, at this time 5 to the right 7421, upside down to 1247, That is the next arrangement: 839651247. Use this method to write out a fully arranged non-recursive calculation
Feeling is quite clear, on the paper a little bit, and then a little verification, really good, and then the implementation of their own PHP a bit:
/* 字典序法获取所有排列 @最后更新时间:03/05/2014 @toryzen(toryzen.com) @备注,备注中示例用ABC顺序表示 */
function getPars( $arr ){ //正向排列 sort( $arr ); //获取数组长度 $len = count ( $arr )-1; //记录传入的排列 $return [] = $arr ; while (TRUE){ //从右侧开始找到第一个左侧(A)<右侧(B)的数字序列 for ( $i = $len ; $i >=0; $i --){ if ( $arr [ $i ]> $arr [ $i -1]){ $here = $i -1; break ; } } //若找到了则开始换位 if ( $here >=0){ //从有右向左侧找,第一个比左侧(A)大的数字(C)交换位置得到CBA for ( $j = $len ; $j > $here ; $j --){ if ( $arr [ $here ]< $arr [ $j ]){ $revers = $j ; list( $arr [ $here ], $arr [ $j ]) = array ( $arr [ $j ], $arr [ $here ]); break ; } } //将后续数字倒序得到CAB unset( $newarr ); for ( $h = $here +1; $h <= $len ; $h ++){ $newarr [] = $arr [ $h ]; unset( $arr [ $h ]); } $return [] = $arr = array_merge ( $arr , array_reverse ( $newarr ,TRUE)); } else { break ; }
} return $return ;
}
$arr = array (1,4,3,2);
print_r(getPars( $arr )); |
In addition to this there is a recursive method, but their own recursive learning is not very good, and all the recursion can be used to solve the cycle with the loop, a day, there is time, and then study recursion, always turn to bend.
Php_ Dictionary ordering method to get permutations and combinations