1. Recursive method
For example, if the collection is {1,3,2}, then all permutations of the elements in this set are {(three-way), (2,1,3), (2,3,1), (3,1,2), (3,2,1)}, and it is clear that given n elements altogether n! different permutations, if the given set is { 1,2,3,4}, you can use the simple algorithm given below to produce all of its permutations, that is, all permutations of the collection (1,2,3,4) are composed of the following permutations:
(1) with 1 opening followed by (2,3,4) arrangement
(2) with 2 opening followed by (1,3,4) arrangement
(3) arrangement with 1,2,4 after 3 opening
(4) After the beginning of the 4, followed by a (three-way) arrangement, which is obviously a recursive idea, so we got the following implementation:
voidSwapint&a,int&b) {a= a ^b; b= a ^b; A= a ^b;}voidPermutation (intBintKintm) {inti,j; if(k = =m) { for(i=0; i<m;++i) cout<<A[i]; cout<<Endl; } Else { for(j=k;j<m;++j) {Swap (&a[k],&A[j]); Permutation (a,k+1, M); Swap (&a[k],&A[j]); } }}
Remove the full array of repeating symbols: Before the exchange can be judged whether the two symbols are the same, not the same exchange, this time need a judge whether the symbol is the same function.
voidSwapint&a,int&b) {a= a ^b; b= a ^b; A= a ^b;}BOOLIsswap (int*a,intBeginintend) { for(inti=begin;i<end;++i) {if(A[i] = =A[end])return false; } return true;}voidPermutation (intBintKintm) {inti,j; if(k = =m) { for(i=0; i<m;++i) cout<<A[i]; cout<<Endl; } Else { for(j=k;j<m;++j) {if(Isswap (A,K,J))//Remove duplicate elements{Swap (&a[k],&A[j]); Permutation (a,k+1, M); Swap (&a[k],&A[j]); } } }}
2, non-recursive implementation
The basic idea is:
1. Sort the initial queue to find the smallest permutation pmin in all permutations.
2. Find the arrangement P (min+1) that is just as small as the pmin.
3. Loop through the second step until one of the largest permutations is found and the algorithm ends.
such as arranging ABCDE, this is the smallest of all permutations of an arrangement, just larger than the ABCDE arrangement is: abced.
The algorithm is as follows:
Given the known sequence P = a1a2a3 ..... An
Sort p by dictionary, get a minimum permutation of P pmin = a1a2a3 .... An, satisfying ai > A (i-1) (1 < i <= N)
Starting with Pmin, find a permutation p (min+1) that is just larger than pmin, and then find an arrangement that is just larger than P (min+1), so repeat.
1. From the back forward (i.e. from AN->A1), find the first pair of adjacent elements ascending, i.e. Ai < A (i+1).
If this AI is not found, it means that the last full permutation has been found and can be returned.
2. From the back forward, find the first number of AJ that is larger than AI, exchanging AI and AJ.
3. Will be arranged in a (i+1) a (i+2) .... An inverse inversion of the number of this sequence, an ... A (i+2) a (i+1). Because from the previous 1th, 2 can be learned that a (i+1) >=a (i+2) >=.....>=an, which is an ascending sequence, the sequence should be reversed, the resulting new arrangement is just like the previous arrangement of large.
4. Repeat step 1-3 until it returns.
voidSwapint*a,intIintj) {A[i]^=A[j]; A[J]^=A[i]; A[i]^=A[j]; } //invert all elements in array a from subscript I to subscript jvoidReverseintA[],intIintj) { for(; i<j; ++i,--j) {swap (A,I,J); } } voidPrintintA[],intlength) { for(intI=0; i<length; ++i) cout<<a[i]<<ends; cout<<Endl; } //find the full arrangement, print the resultsvoidCombination (intA[],intlength) { if(length<2)return; BOOLEnd=false; while(true) {print (a,length); inti,j; //find subscript I for an element that does not conform to the trend for(i=length-2; i>=0; --i) {if(a[i]<a[i+1]) Break; Else if(i==0)return; } for(j=length-1; j>i; --j) {if(A[j]>a[i]) Break; } swap (A,I,J); Reverse (a,i+1, length-1); } }
Generating permutation algorithms