Document directory
- The following describes the full arrangement:
- Full-rank recursive algorithms:
- STL implementation method:
Arrangement and combination are often used in programming...
The combination can be searched or easily solved by bit operations.
For example, if Len numeric num [] is saved, all combinations are obtained...
You can write it like this.
for (int i = 1; i < (1 << len); ++ i)// get zuhe{int len1 = 0;for (int j = 0; j < len; ++ j){if (i & (1 << j)){zuhe[len1 ++] = num[j];}}}
In fact, if there is that number, there will be n corresponding bits, 1 1 1 1 .... These bits can be 0 or 1. Does not 1 to 2 ^ n-1 represent all the situations? Then the okle is proposed as one digit.
The following describes the full arrangement:
First, C ++ STL calls next_permutation directly. Note that this function is ordered from small to large, such as 123. If the initialization is 321, the next one will be gone. If you want to get all, the initialization must be 123 ....
The usage is zuhe []; The array length is len1, and the sequence is initialized...
Do {output zuhe ....
} while (next_permutation(zuhe, zuhe + len1));//qu pai lie
Full-rank recursive algorithms:
The so-called Full arrangement means to output all the elements in the Set in sequence. For example, the full columns of {1, 2, and 3} are 123, 132, 213, 231, 312, and 321. A total of 6 columns meet the calculation formula n! (N indicates the number of elements in the Set, which are not repeated ).
When the elements are not repeated, it is easy to implement the full arrangement using the recursive method. Its Recursive Formula Derivation steps are similar:
1. You must obtain the full arrangement of 123. You only need to obtain the full arrangement of 1 and 23 (1 23, 1 32), and the full arrangement of 2 and 13 (2 13, 2 31), 3 and 12 (321 ).
2. For the full arrangement of 23, you only need to obtain the full arrangement of 2 and 3, and the full arrangement of 3 and 2. The full arrangement of 13 and 12 in step 1 is similar.
3. The full arrangement of 3 or the full arrangement of 2 is their own. Recursion ends.
The implementation code (C ++) of the recursive algorithm for fully arranging non-repeating elements is as follows:
// Exchange a and bvoid swap (int * a, int * B) {int T = * A; * A = * B; * B = T ;} // Full Permutation function. List: list of elements to be sorted, start: subscript of the starting position, and end: the next subscript of the last valid element. Void permutation (INT start, int end, int list []) {int I; If (Start> = END) // recursively ends, print the current full sorting result, and return. {For (I = 0; I <end; I ++) {printf ("% d", list [I]) ;}printf ("\ n "); return;} // for the given list [start... end], so that each element in the interval has the opportunity to put it first, // then start to call itself recursively, get list [start + 1... end. For (I = start; I <end; I ++) {swap (& list [I], & list [start]); // exchange element, this gives every element the opportunity to put it first. Permutation (start + 1, end, list); // recursively call swap (& list [I], & list [start]); // restore the original list, the next recursive call is not affected. }}
The call method of the above program is:
#include <iostream>using namespace std; int main(){ int a[] = {1, 2, 3}; Permutation(0, 2, a); return 0;}
STL implementation method:
When the list of elements to be sorted contains repeated items, the above algorithm needs to be improved. One of the methods can be to maintain a set that stores non-repeated sorting items, and each time a new arrangement is generated, if this arrangement does not exist in the collection, insert the arrangement. Otherwise, discard.
To implement a full Sorting Algorithm with repeated elements, refer to the implementation method of the next_premutation () function in STL (declared in algorithm. h ). This function will arrange the elements in the list in the Lexicographic Order (Wiki) to the next in the full arrangement. Its implementation algorithm is as follows:
The current order is P (0) P (1) P (2)... P (n-1) P (n ). The process of its next arrangement is,
1. Traverse from the back, find the element of the first P (I)> P (I-1), record the subscript I. For example, in the arrangement of 1, 5, 2, 4, 3 to meet the conditions of the element is 4, write down its subscript I = 3, because P (I) is 4, P (I-1) is 2, meeting P (I)> P (I-1 ). If such I is not found, it indicates that the sequence is already the last sequence in the lexicographically ordered sequence and ends the algorithm.
2. Traverse from the back, find the number of the first P (j)> P (I-1), record the subscript K. In the above example, P (I-1) is 2, from the back to the first one greater than P (I-1) is P (4) = 3, so record J = 4.
3. Interchange P (I-1) and P (j) to obtain new sequences 1, 5, 3, 4, 2.
4. Reverse the element between P [I... n] and return the sequence. In the above example, we set 4 and 2 to obtain the final sequence 1, 5, 3, 2, and 4.
The preceding steps are explained using a common example:
Assume that there is a sequence 4, 6, 5, 3, 2, 1, and the next sequence of the Lexicographic Order is required. First, find the first I from the back, so that P (I)> P (I-1), obviously here I is 1, P (I) = 6, which means, all elements after 6 are decreasing by value. Otherwise, 2nd elements 6 will not be found in the first step of I to meet the condition. Now we know that from the beginning to the end of I, it is actually the largest sequence in the Lexicographic Order (it is always decreasing by value ). In the second step, take out the first element P (I-1) = 4 of I and exchange it with the original sequence from the back to the first element greater than it, here, the element exchanged with 4 is 5, and the sequence becomes 5, 6, 4, 3, 2, and 1. So far, the highest bit is upgraded to a level (4-> 5 ), next we need to change the lowest position from the largest to the smallest (like 199 after 200, the highest is from 1 to 2, the lowest position from 99 to the smallest 00 ), the lowest position here is the maximum sequence 6, 4, 3, 2, and 1. You only need to reverse the sequence to change it to 1, 2, 3, 4, and 6, the original sequence is 5, 1, 2, 3, 4, and 6.
The implementation code is as follows:
/*** If the current sequence is in the next Lexicographic Order, true is returned. * Otherwise, false is returned. */Bool next_premutation (INT list [], int length) {int I, j; // Step 1: Obtain I. For (I = length-1; I> 0; I --) {If (list [I]> list [I-1]) {break; // write down subscript I. } If (I <= 0) {// indicates that the current arrangement is the last sequence in the Lexicographic Order, and no more. Return false;} // Step 2: Get J. For (j = length-1; j> 0; j --) {If (list [J]> list [I-1]) {break; // write down the subscript J. } // Step 3: swap list [I-1] and list [J]. Int temp = list [I-1]; list [I-1] = list [J]; list [J] = temp; // Step 4: reverse list [I... n]. Int start, end; For (START = I, end = length-1; Start <end; Start ++, end --) {int temp = list [start]; list [start] = list [end]; list [end] = temp;} return true ;}
To use this method to obtain the full arrangement of a set, you can call the following method (basically the same as the calling method of the STL function next_permutation ):
# Include <iostream>
Using namespace STD;
Int main ()
{
Int list [] = {1, 2, 3, 4, 5 };
Do
{
For (INT I = 0; I <5; I ++)
{
Printf ("% d", list [I]);
}
Printf ("\ n ");
} While (next_premutation (list, 5 ));
Return 0;
}