Next_permutation and Prev_permutation functions of STL specific operations

Source: Internet
Author: User



The next function defaults to the order from small to large, and the pre function defaults to the order of the largest to the smallest;
{3,1,2} results from Next are {3,1,2} and {3,2,1};
The result obtained with the pre is {3,1,2},{2,3,1},{2,1,3},{1,3,2,},{1,2,3};
The principle is as follows:
The principle and use of "STL" next_permutation
1, Encounter Next_permutation (permutation: The meaning of the sequence)
Today, a simple question (srm531-division Two-level one) is encountered on the TC, which is the smallest dictionary sequence (Sequence of numbers A is lexicographically smaller th) that is not sorted in ascending order for a given array. A B If a contains a smaller number on the first position on which they differ).
The solution is simply to sort the array (ascending) and then find the first position to swap from the end of the head (because there may be duplicate numbers).
Finally look at other people's solution, after sorting, using a function of the STL next_permutaion, directly to the first not in ascending order of the sequence.
2, Next_permutation realization principle
In the "STL Source code Analysis" found this function, here is also a brief description of the principle:
In STL, in addition to Next_permutation, there is a function prev_permutation, both of which are used to calculate the permutation of the combination of functions. The former is to find the next permutation combination, while the latter is to find the previous permutation. The so-called "next" and "last", the book cited a simple example: the sequence {A, B, c}, each element is smaller than the following, according to the dictionary sequence, fixed A is smaller than BC, C is larger than B, its next sequence is {A, C, b}, and {A, C, b} The previous sequence is {a, b, C}, the same can be introduced for all six sequences: {A, B, C}, {A, C, b}, {B, A, c}, {B, C, a}, {C, a, b}, {C, B, a}, where {A, B, C} have no previous element, {C, B, a} have no next element.
The function prototypes for Next_permutation are as follows:
CPP code copy Code Collection code
1.template<class bidirectionaliterator>
2.bool Next_permutation (
3. Bidirectionaliterator _first,
4. Bidirectionaliterator _last
5.);
6.template<class Bidirectionaliterator, Class binarypredicate>
7.bool Next_permutation (
8. Bidirectionaliterator _first,
9. Bidirectionaliterator _last,
Ten. Binarypredicate _comp
11.);
For the third parameter of the second overloaded function, the default comparison order is less than. Returns true if the next sequence is found, otherwise false.
The function implementation principle is as follows:
In the current sequence, two adjacent elements are searched forward from the end, the previous one is *i, the latter is *ii, and *i < *ii are satisfied. And then looking for another element from the end *j, if *i < *j is satisfied, the first element is swapped with the J element, and all elements after the second element (including II) are reversed, the next sequence is obtained.
The code is implemented as follows:
CPP code copy Code Collection code
1.template<class bidirectionaliterator>
2.bool Next_permutation (
3. Bidirectionaliterator First,
4. Bidirectionaliterator Last
5.)
6.{
7. if (first = = last)
8. return false; Empty sequence
9.
Ten. Bidirectionaliterator i = first;
One. ++i;
if (i = = last)
return false; One element, no next sequence.
14.
i = last;
-----I.;
17.
for (;;) {
Bidirectionaliterator II = i;
I.-I;
if (*i < *ii) {
Bidirectionaliterator j = lase;
. while (! ( *i < *--j));
24.
Iter_swap (i, j);
Reverse (ii, last);
. return true;
28.}
29.
if (i = = first) {
Reverse (first, last); All reverse, that is, the most dictionary sequence, such as CBA into ABC
return false;
33.}
34.}
35.
36.}
Prev_permutation implementation is similar to reverse lookup
3. Using Next_permutation
Think of the question, what is the next sequence of sequences {A, D, C, E, b}? Use the previous analysis to launch the answer and validate it with your code.
Here I use arrays and vectors to represent the sequence, using Next_permutation to get the next sequence (compilation Environment: dev-c++):
CPP code copy Code Collection code
1. #include <cstdlib>
2. #include <iostream>
3. #include <algorithm>
4. #include <vector>
6.using namespace Std;
8.void Testarray ()
9.{
Char chs[] = {' A ', ' d ', ' C ', ' E ', ' B '};
One. int count = sizeof (CHS)/sizeof (char);
Next_permutation (chs+0, CHS + count);
. printf ("testarray:\n");
(int i = 0; i < count; i++) {
. printf ("%c\t", Chs[i]);
18.}
printf ("\ n");
21.}
23.void Testvector ()
24.{
Char chs[] = {' A ', ' d ', ' C ', ' E ', ' B '};
. int count = sizeof (CHS)/sizeof (char);
Vector<char> Vchs (CHS, CHS + count);
Next_permutation (Vchs.begin (), Vchs.end ());
printf ("testvector:\n");
Vector<char>::iterator ITR;
for (ITR = Vchs.begin (); ITR! = Vchs.end (); itr++) {
printf ("%c\t", *ITR);
35.}
printf ("\ n");
37.}
39.int Main (int argc, char *argv[])
40.{
Testarray ();
printf ("\ n");
Testvector ();
System ("PAUSE");
Exit_success return;
47.}
4. Summary
It is convenient to use next_permutation and prev_permutation to arrange the combination, but remember to include the header file # include <algorithm>.
Although the last permutation does not have the next arrangement, Next_permutation returns false, but with this method, the sequence becomes the first of the dictionary sequence, such as the CBA becomes ABC. Prev_permutation.
STL usage of the full permutation problem (Next_permutation Class)
Standard library fully arranged next_permutation ()
In the standard library algorithm, the Next_permutation application is widely used in the sequence operation. This function calculates the entire array of data. But how to use, how the principle, I did a simple analysis.
First look at the relevant information in the STL.
Function Prototypes:
Template<class bidirectionaliterator>
BOOL Next_permutation (
Bidirectionaliterator _first,
Bidirectionaliterator _last
);
Template<class Bidirectionaliterator, Class binarypredicate>
BOOL Next_permutation (
Bidirectionaliterator _first,
Bidirectionaliterator _last,
Binarypredicate _comp
);
Two overloaded functions, the second with the predicate parameter _comp, with only two arguments in the version, and the default predicate function is "less than".
return value: type bool
Analyze the Next_permutation function execution process:
Suppose the series D1,d2,d3,d4 ...
The range is marked by [First,last], which calls next_permutation to increment the sequence by a dictionary order. For example, in the alphabet, the next word of ABCD is arranged as ABDC, but there is a key point, how to determine the next permutation in the dictionary order, not next->next->next ...
If the current call arrangement reaches the maximum dictionary order, such as DCBA, it returns false, and the arrangement is reset to the dictionary order.
A return of TRUE indicates that the next array of builds succeeded. The following focuses on this process:
The next two data are compared from the backward to the mark, if the former is less than (the default is less than) the latter, the former is X1 (position px) will be replaced, again after re-search the first one is not less than X1 data, marked as X2. Swap the X1,X2 and then set the [Px+1,last] tag range to reverse. Complete.
Important: Why this ensures that the minimum increment is obtained.
Starting from location first the data position of the original sequence and the new series is PX, and the new data is X2. [Px+1,last] is always decremented, [first,px] does not change, because x2>x1, so no matter how the X2 behind the order is larger than the original sequence, inversion [px+1,last] to make this sub-series (increment) is minimal. The new sequence is thus guaranteed to be the dictionary order of the original sequence next.
After understanding this principle, look at the following example:
int main () {
int a[] = {3,1,2};
do{
cout << a[0] << "<< a[1] <<" "<< a[2] << Endl;
}
while (Next_permutation (a,a+3));
return 0;
}
Output: 312/321 because the original sequence does not begin with the dictionary arrangement.
So to get all the full array
int a[] = {3,1,2}; Change to int a[] = {n/a};
In addition, another function in the library, Prev_permutation, is the same as next_permutation, which is the last permutation in the dictionary order from the original arrangement.
So
int main () {
int a[] = {3,2,1};
do{
cout << a[0] << "<< a[1] <<" "<< a[2] << Endl;
}
while (Prev_permutation (a,a+3));
return 0;
}
To get all the permutations of 123.
--------------------------------------------------------------------------------------------------------------- ------------------------------
Last week, I saw a problem, implementation can input any string, can give all its possible permutations of the case. Think for a while, with their knowledge is not able to handle (of course, not long, very unfamiliar, and the level of this is not high), search on the internet, arrived at the results, posted solutions, not too to keep abreast of the development of the comrades can draw on. In fact, there is not much difficulty, now the C + + language provides a ready-made algorithm to solve the permutation problem, they are next_permutation and prev_permutation, it is important to note that "if you want to go through all the arrangement, you must first sort the elements." The following is reproduced: <<c++ standard library >> This book, when you see the "Sequencing algorithm" section, found two function next_permutation, prev_permutation for our usual arrangement of the problem is very helpful, Two test functions were written according to the description in the book:
void Func1 ()
{
Vector<int> v;
Insert_elements (v, 1,3);
Print_elements (V, "myself:");
while (Next_permutation (V.begin (), V.end ()))
{
Print_elements (V, "");
}
}
void Func2 ()
{
Vector<int> v;
Insert_elements (v, 1,3);
Print_elements (V, "myself:");
Sort (V.begin (), V.end (), greater<int> ()); Increase sort (descending)

while (Prev_permutation (V.begin (), V.end ()))
{
Print_elements (V, "");
}
}
If we encounter a similar problem in the future, we will do so, no more brains, people have ready-made functions, directly to use it.
Outside the popular:
This paragraph is the real algorithm, STL inside the source code
Template inline
BOOL Next_permutation (_bidit _first, _bidit _last)
{//Permute and test for pure ascending, using operator<
_bidit _next = _last;
if (_first = = _last | | _first = =--_next)
return (false);
for (;;)
{//find rightmost element smaller than successor
_bidit _next1 = _next;
if (*--_next < *_NEXT1)
{//swap with rightmost element, ' s smaller, flip suffix
_bidit _mid = _last;
for (;!) ( *_next < *--_mid); )
;
Std::iter_swap (_next, _mid);
Std::reverse (_next1, _last);
return (true);
}
if (_next = = _first)
{//Pure descending, flip all
Std::reverse (_first, _last);
return (false);
}
}
}
Ps: "STL": Standard Template Library (excerpt bbs.csdn.net)
This was first completed by Alexander Stepanov and Meng Lee (like the Chinese name), which was presented to the ANSI/ISO standard C + + committee in 1994 and passed as part of standard C + +. Words too literally this is a code base standard, not a grammar standard. To put it simply, STL is a set of code bases based on template syntax in C + + that contains the underlying data structures and algorithms. STL is characterized by the realization of "type parameterization", that is, the STL code can handle any custom type of object, if you do not use template technology, this is a very difficult thing. For this reason, support for template syntax has been added to the latest Java and C # syntax, which can be seen as important. Another important topic for STL is GP (Generic programming), generics. This is another programming model that is parallel to object-oriented, which is based on templates, weakening the differences of entity types, simplifying the model of problem abstraction in programming, providing better encapsulation and elasticity, and undoubtedly a relief for complex object-oriented programming, at least in the spirit. GP is a research hotspot in software architecture in recent years, but the real application in China seems to be rare.

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Next_permutation and Prev_permutation functions of STL specific operations

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.