定义于头文件 <algorithm>
算法库提供大量用途的函数(例如查找、排序、计数、操作),它们在元素范围上操作。注意范围定义为 [first, last)
,其中 last
指代要查询或修改的最后元素的后一个元素。
产生某个元素范围的按字典顺序的下一个较大的排列
std::next_permutation
template< class BidirIt > | (1) | (C++20 前) |
template< class BidirIt > | (C++20 起) | |
template< class BidirIt, class Compare > | (2) | (C++20 前) |
template< class BidirIt, class Compare > | (C++20 起) |
变换范围 [first, last)
为来自所有按相对于 operator<
或 comp
的字典序的下个排列。若这种排列存在则返回 true ,否则变换范围为首个排列(如同用 std::sort(first, last)
)并返回 false 。
参数
first, last | - | 要重排的元素范围 |
comp | - | 比较函数对象(即满足比较 (Compare) 要求的对象),若首个参数小于第二个,则返回 true 。 比较函数的签名应等价于如下: bool cmp(const Type1 &a, const Type2 &b); 虽然签名不必有 const & ,函数也不能修改传递给它的对象,而且必须接受(可为 const 的)类型 |
类型要求 | ||
- BidirIt 必须满足值可交换 (ValueSwappable) 和 遗留双向迭代器 (LegacyBidirectionalIterator) 的要求。 |
返回值
若新排列按字典序大于旧者则为 true 。若抵达最后重排并重置范围为首个排列则为 false 。
异常
任何从迭代器操作或元素交换抛出的异常。
复杂度
至多 N/2 次交换,其中 N = std::distance(first, last) 。
典型实现在排列的整个序列上,平均每次调用使用约 3 次比较和 1.5 次交换。
可能的实现
template<class BidirIt>
bool next_permutation(BidirIt first, BidirIt last)
{
if (first == last) return false;
BidirIt i = last;
if (first == --i) return false;
while (true) {
BidirIt i1, i2;
i1 = i;
if (*--i < *i1) {
i2 = last;
while (!(*i < *--i2))
;
std::iter_swap(i, i2);
std::reverse(i1, last);
return true;
}
if (i == first) {
std::reverse(first, last);
return false;
}
}
}
调用示例
#include <iostream>
#include <algorithm>
#include <functional>
#include <vector>
#include <iterator>
#include <time.h>
using namespace std;
struct Cell
{
int x;
int y;
Cell &operator +=(const Cell &cell)
{
x += cell.x;
y += cell.y;
return *this;
}
bool operator <(const Cell &cell) const
{
if (x == cell.x)
{
return y < cell.y;
}
else
{
return x < cell.x;
}
}
bool operator ==(const Cell &cell) const
{
return x == cell.x && y == cell.y;
}
};
std::ostream &operator<<(std::ostream &os, const Cell &cell)
{
os << "{" << cell.x << "," << cell.y << "}";
return os;
}
int main()
{
std::mt19937 g{std::random_device{}()};
srand((unsigned)time(NULL));;
std::cout << std::boolalpha;
auto func1 = []()
{
int n = std::rand() % 10 + 100;
Cell cell{n, n};
return cell;
};
// 初始化cells1
vector<Cell> cells1(5);
std::generate(cells1.begin(), cells1.end(), func1);
// 打印cells1
std::cout << "cells1: ";
std::copy(cells1.begin(), cells1.end(), std::ostream_iterator<Cell>(std::cout, " "));
std::cout << std::endl;
for (size_t index = 0; index < 6; index++)
{
//变换范围 [first, last) 为来自所有按相对于 operator< 或 comp 的字典序的下个排列
std::next_permutation(cells1.begin(), cells1.end());
std::cout << "next_permutation: ";
std::copy(cells1.begin(), cells1.end(), std::ostream_iterator<Cell>(std::cout, " "));
std::cout << std::endl;
}
std::cout << std::endl;
std::cout << std::endl;
std::cout << std::endl;
auto comp = [](const Cell & a, const Cell & b)
{
if (a.x == b.x)
{
return a.y < b.y;
}
return a.x < b.x;
};
// 初始化cells2
vector<Cell> cells2(5);
std::generate(cells2.begin(), cells2.end(), func1);
// 打印cells1
std::cout << "cells2: ";
std::copy(cells2.begin(), cells2.end(), std::ostream_iterator<Cell>(std::cout, " "));
std::cout << std::endl;
for (size_t index = 0; index < 6; index++)
{
//变换范围 [first, last) 为来自所有按相对于 operator< 或 comp 的字典序的下个排列
std::next_permutation(cells2.begin(), cells2.end(), comp);
std::cout << "next_permutation: ";
std::copy(cells2.begin(), cells2.end(), std::ostream_iterator<Cell>(std::cout, " "));
std::cout << std::endl;
}
return 0;
}
输出