This articleReprinted fromDong's blog: http://dongxicheng.org/structure/permutation-combination/
1. Preface
This article introduces common permutation and combinationAlgorithmIncluding the full sorting algorithm, the full combination algorithm, and N combination algorithms for M numbers.
2. Arrangement Algorithm
Common sorting algorithms include:
(A) lexicographic Method
(B) incremental carry-in method
(C) decimal carry-in method
(D) adjacent-position swap Method
(E) Recursion
Two common methods are introduced.:
(1) lexicographic Method
A sequential relationship is defined for characters in a given character set, and each order is generated in sequence.
[Example] the character set {1, 2, 3} is smaller than the first digit. In this way, 123,132,213,231,312,321 is generated in the lexicographically ascending order.
Generate the next arrangement for a given full arrangement. The next one is a string that is not adjacent to the next one in a dictionary order. This requires that this one and the next one have the same prefix as long as possible, that is, the change is limited to the suffix as short as possible.
Algorithm IDEA:
Set P to 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, replace PJ + 1... Pk-1PjPk + 1... Pn flip, p' = P1P2... Pj-1PkPn... PK + 1pjpk-1... PJ + 1 is the next of P
Example: Next arrangement of 839647521.
Start from the rightmost, find the first number 4 (because 4 <7, and 7> 5> 2> 1), and then start from the rightmost, find the number 5 (because 4> 2> 1 and 4 <5) on the Right of 4, and switch 4 and 5. At this time, the value on the Right of 5 is 7421, and the value is inverted to 1247, the next order is 839651247. this method is used to write a non-recursive algorithm with full arrangement as follows:
This method supports data duplication and is used in C ++ STL.
(2) Recursion
Set a group of numbers P = {R1, R2, R3 ,... , Rn}, the full row column is perm (P), Pn = p-{Rn }. Then perm (p) = r1perm (P1), r2perm (P2), r3perm (P3 ),... , Rnperm (PN ). When n = 1, Perm (p} = R1.
For example: Find the full arrangement of {1, 2, 3, 4, 5}
1. First, check the last two numbers 4 and 5. Their full columns are 4 5 and 5 4, that is, the full arrangement of 5 starting with 4 and the full arrangement of 4 starting with 5.
Because the full arrangement of a number is itself, the above results are obtained.
2. Check the last three values: 3, 4, and 5. Their full columns are 3 4 5, 3 5 4, 4 3 5, 4 5 3 3, 5 3 4, 5 4 3 6 groups.
That is, a combination starting with 3 and a combination of 4 and 5, a combination starting with 4 and a combination of 3 and 5, and a combination starting with 5 and a combination of 3 and 4.
# Include <stdio. h> int n = 0; void swap (int * a, int * B) {int m; M = * A; * A = * B; * B = m ;} void perm (INT list [], int K, int m) {int I; If (k> m) {for (I = 0; I <= m; I ++) printf ("% d", list [I]); printf ("\ n"); N ++;} else {for (I = K; I <= m; I ++) {swap (& list [K], & list [I]); perm (list, k + 1, m); swap (& list [K], & list [I]) ;}}int main () {int list [] = {1, 2, 3, 4, 5}; perm (list, 0, 4); printf ("Total: % d \ n", n); Return 0 ;}
3. Combined Algorithms
3.1 full combination
This section describes the binary conversion method, that is, to map each combination with a binary number, and enumerate each combination while enumerating the binary. Such as string: ABCDE
00000 <-> null
00001 <-> E
00010 <-> d
... ...
11111 <-> ABCDE
3.2 select m from N
(1) Recursion
A. Select the maximum number of N numbers from the N number, and then select the number of m-1 in the remaining n-1 numbers until 1 is selected from the number of N-(m-1.
B. Select a smaller number from N to continue with Step 1 until the maximum number of available numbers is M.
The implementation of recursive methods is as follows:
/// Obtain all the combinations of any M elements from array a [1 .. n. /// A [1. N] indicates the candidate set. N indicates the large and small candidate set, and N> = m> 0. /// B [1 .. m] is used to store the elements in the current combination (the element subscript is stored here), // constant M indicates the number of elements in a combination that meet the conditions, M = m, these two parameters are only used to output results. Void combine (int A [], int N, int M, int B [], const int m) {for (INT I = N; I> = m; I --) // note the loop range here {B [M-1] = I-1; if (M> 1) Combine (A, I-1, S-1, B, M ); else // M = 1, output a combination {for (Int J = M-1; j> = 0; j --) cout <A [B [J] <"; cout <Endl ;}}}
(2) 01 Conversion Method
BenProgramThe idea is to open an array. Its subscript indicates the numbers 1 to n. The value of the array element 1 indicates that the number represented by it is selected. If it is 0, it is not selected.
First initialize, set the first n elements of the array to 1, indicating that the first element is combined with the first n.
Scan the "10" combination of array element values from left to right, find the first "10" combination, and change it to the "01" combination, at the same time, move all "1" on the left to the leftmost end of the array.
When the first "1" is moved to the n-m position of the array, that is, when all N "1" is moved to the rightmost end, the last combination is obtained.
For example, find the combination of 3 in five:
1 1 1 0 0 //, 3 1 1 0 1 0/, 4 1 0 1 1 0/, 4 0 1 1 0, 4 1 1 0 0 1/1/1, 5 1 0 1 0 1/1, 5 0 1 1 0 1/2, 5 1 0 0 1 1, 5 0 1 0 1 1 // 2, 4, 5 0 0 1 1 // 3, 4, 5
4. References
(1) http://www.cnblogs.com/nokiaguy/archive/2008/05/11/1191914.html
(2) http://comic.sjtu.edu.cn/thucs/GD_jsj_025y/text/chapter01/sec05/default.htm
(3) http://blog.csdn.net/sharpdew/archive/2006/05/25/755074.aspx
(4) http://xiaomage.blog.51cto.com/293990/74094