Goal
The Next_permutation function in STL and the prev_permutation two function provide a function for a specific arrangement p, and then a permutation p+1 and the previous arrangement P-1.
Here we take next_permutation as an example to analyze the principle of the implementation of STL, the principle of prev_permutation similar, we at the end of the comparison of their implementation differences
Problem:
Given a permutation p, find out what the next permutation p+1 is.
Ideas
According to the definition of dictionary order is not difficult to launch, the positive sequence, is a set of the smallest arrangement, and reverse, is a set of the largest arrangement.
From the definition of the dictionary order, we can see that n elements of the arrangement of the whole arrangement, from the given permutation p to solve the next permutation p+1, assuming that two permutations have the former K-bit is the same (0<=k<=n), then we only need to n-k elements in the following arrangement P (N-K) In the next arrangement .
Since we are concerned with the arrangement of the n-k in the back, it is advisable to open the brain hole and arrange it from the rear.
First, let's take a more extreme example: permutation 1 2 3 4 5
It is clear that this is a positive order (increment sequence), so this is the smallest permutation of the permutations of these numbers, recorded as P1.
Now we ask for P2, P2 is 1 2 3 5 4. We can see that the first three bits of the P2 and the P1 of the first three are exactly the same, and the only change is the final two-bit reversal order , what is the upside of this order? --Makes the last two bits from the positive sequence of 4 5 into reverse 5 4.
Then seek P3. P3 is 1 2 4 3 5. We see that the last two digits are already in reverse order, there is no way to have a larger dictionary order, so we have to consider more bits, in the latter 3 elements,3 5 4 is obviously not in reverse order, so there must be a larger dictionary order arrangement, we have determined the n-k==3
We are now going to find the next permutation in 3 5 4, 3 5 4 is not a reverse order, because 3 is behind the element greater than 3. We want to select the smallest of the numbers greater than 3, and the 3 swap, as this guarantees the smallest first element. For this example, we choose to swap 3 and 4 instead of 3 and 5, so the first element we get is 4. Now we get the permutations 4 5 3.
Obviously, 4 5 3 is not the next arrangement we want, the next permutation is 4 3 5. Observe the difference, it is not difficult to see, the first element must be 4, but 5 3 This sub-arrangement is a reverse order .
Why is it in reverse order?
Because we are looking for the time is not reversed for the split point, 3 happens to be the first non-reverse elements, and 4 as the 3 exchange of elements, and more than 3 is larger, so the exchange of the resulting 5 3 must be in reverse order.
There is no next arrangement in reverse order, but the reverse is reversed, we get the corresponding positive sequence arrangement, and the positive sequence is the current element can form the smallest arrangement, so, 4 3 5 is 4 for the first element can form the smallest arrangement, and the first 3 bits did not change, so we got the next permutation P3.
In addition, the smallest element greater than 3, which is 4, is also the first element greater than 3, because 5 4 is an inverted order .
More generally, for example for a re-set arrangement 1 2 3 7 6 5 2 1
We first look for the first non-reverse element, here is 3, and then from the back forward to find the first element greater than 3, here is 5, Exchange, get 5 7 6, 3 2 1 sub-arrangement, and then reverse, you can get the next arrangement. If the first non-reverse element is not found, then the arrangement is already the largest arrangement.
Code implementation:
Take the string, for example, to implement Next_permutation, where the empty for statement is mainly to press the line
1 /*2 * Algorithm implementation: next_permutation implementation in STL3 */4#include <cstdio>5#include <cstring>6 7 voidInline Swap (Char(SS,Char*12) {8 Chart=*S1;9*s1=*S2;Ten*s2=T; One } A /** - * Inverse string function, s,e the beginning and end of the string, cannot invert the Chinese - **/ the voidReverseChar*s,Char*e) { - for(e--;s<e;s++,e--) swap (s,e); - } - + BOOLNext_permutation (Char*start,Char*end) { - Char*cur = end-1, *pre=cur-1; + while(Cur>start && *pre>=*cur) cur--, pre--; A if(Cur<=start)return false; at - for(cur=end-1; *cur<=*pre;cur--);//find the smallest element of an element that is greater than *pre in reverse order - swap (cur,pre); -Reverse (pre+1, end);//turn the reverse of the tail into a positive order - return true; - } in - intMain () { to Chars1[]="01224", s2[]="8000"; +Reverse (s1,s1+strlen (S1)); -printf"%s\n", S1); the intn=strlen (S2); *Puts"Next Arrangement:"); $ intCnt=0;Panax Notoginseng Do{ - puts (S2); thecnt++; +} while(Next_permutation (s2,s2+n)); Aprintf"%d", CNT); the}
All the symbols in the next_permutation of the preceding code that are related to the contents of the pre and cur pointers are reversed, and the Prev_nextpermutation
The code is as follows:
1 BOOLPrev_permutation (Char*start,Char*end) {2 Char*cur = end-1, *pre=cur-1;3 while(Cur>start && *pre<=*cur) cur--, pre--;//There's a change in the sign4 if(Cur<=start)return false;5 6 for(cur=end-1; *cur>=*pre;cur--);//There's a change in the sign7 swap (cur,pre);8Reverse (pre+1, end);9 return true;Ten}
Well, finally solve the heart of a great confusion, but also hope to help you ~ goodnight ~ La La ~ ̄▽ ̄ (~*)
The principle and self-realization of STL next_permutation algorithm