Use next_permutation to calculate the full Arrangement

Source: Internet
Author: User

In the standard library algorithm, next_permutation is widely used in series operations. This function can calculate the full arrangement of a group of data. But I made a simple analysis on how to use it and how it works.

First, view related information in STL.
Function prototype:

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 predicate parameter _ comp, with only two versions. The default predicate function is "less ".

Return Value: bool type

Analyze the next_permutation function execution process:

Suppose the number of series D1, D2, D3, D4 ......

The range is marked by [first, last), and next_permutation is called to increase the number of columns one by one. This increment process is in the lexicographically ascending order. For example, in the alphabet, the next word of ABCD is arranged as ABDC. However, there is a key point: how can we determine the next word in the Lexicographic Order, instead of next-> next ......

If the current call order reaches the maximum Lexicographic Order, for example, dcba, false is returned, and this Lexicographic Order is reset to the minimum Lexicographic Order.

True indicates that the next sorting is successfully generated. The following describes the process:

Compare two adjacent data based on the mark from the back to the front. If the former is smaller than (the default value is smaller than) and the former is x1 (the position Px), it indicates it will be replaced, repeat and search for the first data not less than X1, marked as X2. Exchange x1, x2, and set the range of the [px + 1, last) tag to inverse. Complete.

Key point: why can we guarantee a minimum increment.

Starting from position first, the Data Location of the original series and the new series is PX, and the new data is X2. [Px + 1, last) is always decreasing, and [first, PX) is not changed, because X2> X1, so no matter how the column after X2 is bigger than the original series, if [px + 1, last) is reversed, this subsequence (incrementing) is minimized. Thus, the new sequence is ordered by the lexicographically next of the original sequence.

After understanding this principle, let's 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 start from the smallest dictionary arrangement.

Therefore, you need to get all the rows in full order.

Int A [] = {3, 1, 2}; change to int A [] = {1, 2, 3 };

In addition, another function in the database, prev_permutation, is opposite to next_permutation. From the original arrangement, the last most recent arrangement in the Lexicographic Order is obtained.

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;
}

In order to get all the 123 orders.

**************************************** **************************************** ******************

**************************************** **************************************** ******************

Next_permutation can be used in the algorithm header file to generate a complete arrangement. The source code is analyzed as follows:

Template <class _ bidit> inline
Bool _ next_permutation (_ bidit _ first, _ bidit _ last)
{// Permute and test for pure ascending, using operator <

//-----------------------------------------------\
_ Debug_range (_ first, _ last );
_ Bidit _ next = _ last;
If (_ first = _ last | _ first = -- _ next)
Return (false );

// The above part checks the boundary range

//-----------------------------------------------/

For (;;)
{// Find rightmost element smaller than successor
_ Bidit _ next1 = _ next;
If (_ debug_lt (* -- _ next, * _ next1 ))
{// Swap with rightmost element that's smaller, flip suffix
_ Bidit _ mid = _ last;
For (;! _ Debug_lt (* _ next, * -- _ mid );)
;
STD: iter_swap (_ next, _ mid );

// The comments in the left side have been quite clear. From the rightmost side, compare the elements adjacent to each other until you find the one on the right that is bigger than the one on the left.

// It is the one to be replaced, and then find the first one greater than this element from the rightmost side to exchange the two of them.
STD: reverse (_ next1, _ last );

// After switching, flip all elements behind the switching element
Return (true );
}

If (_ next = _ First)
{// Pure descending, flip all
STD: reverse (_ first, _ last );
Return (false );
}
}
}

The key is to determine what is the next arrangement of an arrangement, I can see clearly but do not understand, so paste a paragraph, the following from the http://www.cppblog.com/yindf/archive/2010/02/24/108312.html

ABCD next_permutation-> ABDC

So why is next to abcd abdc rather than acbd?

To put it simply, replace A, B, C, and D with 1, 2, 3, and 4. You can get the following information:

Originally arranged intermediate conversion value
1, 2, 3, 4, 3, 2, 1 (3 * (3) + 2) * (2) + 1) * (1) = 23
1, 2, 4, 3, 2, 0 (3 * (3) + 2) * (2) + 0) * (1) = 22
1, 3, 2, 4, 3, 1, 1 (3 * (3) + 1) * (2) + 1) * (1) = 21
1, 3, 1, 0 (3 * (3) + 1) * (2) + 0) * (1) = 20
, 1 (3 * (3) + 0) * (2) + 1) * (1) = 19
...
...
...
, 0 (0 * (3) + 0) * (2) + 0) * (1) = 0
||
||
|

The intermediate conversion above refers to the number of digits after each number greater than the current digit. For example:

In, 1 is followed by (3, 4, 2) They are all greater than 1, so the first is 3
3 is followed by (4, 2), but only 4 is greater than 3, so the second is 1
4 is followed by (2), not greater than 4, so the third digit is 0
The last digit is certainly not larger, so a 0 is omitted.

After this conversion, a representation (intermediate conversion) is obtained, which corresponds to the original arrangement and can be converted to each other.

Observe this intermediate expression carefully and find that the first and second bits can only be (,), the second bits can only be (, 2), and the third bits can only be ). Generally, numbers are represented in decimal notation and binary in the computer. But now, I use a special hexadecimal notation to represent numbers:

The first digit is in hexadecimal notation, and the second digit is in hexadecimal notation...

Then we get the decimal value of this intermediate representation. For example:

Level
|
1, 1, 0 ----> (1 * (3) + 1) * (2) + 0) * (1) = 8

3, 1, 0 ----> (3 * (3) + 1) * (2) + 0) * (1) = 20

In this way, we can obtain a one-to-one correspondence between a decimal number and an arrangement.
Now there is a one-to-one correspondence between the number of permutation and the ordered decimal number (by changing the correspondence, you can make the decimal number in ascending order ).

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.