C++ Primer notes - arrangement algorithm (next_permutation, prev_permutation, is_permutation)

Table of contents

overview

①next_permutation

②prev_permutation

③is_permutation


overview

Pages: P778 (A.2.7 Arrangement Algorithms) 

Header file: <algorithm>

Function name: next_permutation & prev_permutation & is_permutation

C++ provides us with algorithms specifically for permutations. These algorithms can automatically arrange the content in lexicographical order.

For example: Now there are characters a, b, and c, and we want to know how many combinations of these three characters there are, then we can use the permutation algorithm.

①next_permutation

bool next_permutation(iterator first, iterator last);

bool next_permutation(iterator first, iterator last, compare comp);

The first two parameters are the head and tail iterators of the sequence to be arranged. The third parameter is a custom arrangement, and the default is lexicographical order.

Each permutation will change the combination of arrays and return true. It is necessary to process the arrays forward and backward, so a bidirectional iterator should be used .

After sorting to the last form (the sequence with the largest lexicographical order), the sequence will be sorted into the smallest form, and false will be returned at the same time.

Two points are worth noting:

1. The way of arrangement is that the sequence is from left to right according to the lexicographical order from small to large, taking abc as an example: the arrangement is abc, acb, bac, bca, cab, cba.

This is because the first (leftmost) element of abc is smaller than the first element of any other permutation, and the second element is smaller than any other element, and so on.

2. next_permutation is not to sort out all the sequences, but to arrange them backwards according to the initial situation of the sequence. For example, if the input sequence is bac, then the sequence can only be bac, bca, cab, cba.

Sample code:

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int main()
{
	vector<int> arr = { 1, 2, 3 };
	do
	{
		for (auto n : arr) cout << n << " ";
		cout << endl;
	} 
	while (next_permutation(arr.begin(), arr.end()));
	return 0;
}

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int main()
{
	vector<int> arr = { 2, 3, 1 };
	do
	{
		for (auto n : arr) cout << n << " ";
		cout << endl;
	} 
	while (next_permutation(arr.begin(), arr.end()));
	return 0;
}

②prev_permutation

The usage is similar to next_permutation, except that the function is reversed, that is, it is arranged forward from the starting sequence. Also take abc as an example, if the input sequence is bac, then the output of prev_permutation is bac, acb, abc.

The diagram is as follows:

Code example:

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int main()
{
	vector<int> arr = { 3, 2, 1};
	do
	{
		for (auto n : arr) cout << n << " ";
		cout << endl;
	} 
	while (prev_permutation(arr.begin(), arr.end()));
	return 0;
}

③is_permutation

This function is used to determine whether a particular sort belongs to the sequence.

bool next_permutation(iterator first1, iterator last1, iterator first2);

 The first two parameters of the function are the head and tail iterators of the specified sort, and the third parameter is the start iterator of a certain sequence.

Returns true if such sorting exists in the sequence; false if it does not.

Of course, there are two points to note here:

1. The length of the specified sort needs to be less than or equal to the sequence length.

2. The third parameter does not have to be a header iterator. For example: If the specified sort is bac, and the sequence is fabc, then the third parameter can be beign() + 1, that is, start from a and only arrange letters abc. Of course, how many letters are arranged depends on the length of the specified sort, here is 3. This is why the length of the specified sort can be less than the length of the sequence.

Code example:

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
using namespace std;
int main()
{
	vector<int> arr = { 3, 2, 1 };
	vector<int> tmp = { 1, 2, 3 };
	if (is_permutation(arr.begin(), arr.end(), tmp.begin()))
	{
		cout << "right" << endl;
	}
	else cout << "false" << endl;
	return 0;
}

 Special case:

...
vector<int> arr = { 3, 2, 1 };
vector<int> tmp = { 4, 1, 2, 3 };
//没有从头迭代器开始排序, 待排序的序列元素为 1 2 3 
if (is_permutation(arr.begin(), arr.end(), tmp.begin() + 1))
    ...

...
vector<int> arr = { 3, 2, 1 };
vector<int> tmp = { 1, 2, 3, 4 };
//没有从头迭代器开始排序, 待排序的序列元素为 2 3 4
if (is_permutation(arr.begin(), arr.end(), tmp.begin() + 1))
    ...


Please correct me if there is any mistake

Guess you like

Origin blog.csdn.net/weixin_61857742/article/details/130367516