std::prev_permutation
Определён в заголовочном файле <algorithm> | ||
|---|---|---|
template< class BidirIt > bool prev_permutation( BidirIt first, BidirIt last ); | (1) | (constexpr с C++20) |
template< class BidirIt, class Compare > bool prev_permutation( BidirIt first, BidirIt last, Compare comp ); | (2) | (constexpr с C++20) |
Преобразует диапазон [first, last) в предыдущую перестановку. Возвращает true, если такая перестановка существует; в противном случае преобразует диапазон в последнюю перестановку (в порядке убывания) и возвращает false.
std::less{}(с C++20).comp.Если тип *first не удовлетворяет требованиям Swappable(до C++11)BidirIt не удовлетворяет требованиям ValueSwappable(с C++11), поведение не определено.
Параметры
| first, last | - | пара итераторов, задающая диапазон переставляемых элементов |
| comp | - | объект функции сравнения (то есть объект, удовлетворяющий требованиям Compare), который возвращает true, если первый аргумент меньше второго.Сигнатура функции сравнения должна быть эквивалентна следующей: boolcmp(constType1&a,constType2&b); Хотя сигнатура не обязана содержать |
| Требования к типам | ||
-BidirIt должен удовлетворять требованиям ValueSwappable и LegacyBidirectionalIterator. |
||
Возвращаемое значение
true, если новая перестановка предшествует старой в лексикографическом порядке. false, если достигнута первая перестановка и диапазон был преобразован в последнюю перестановку.
Исключения
Любые исключения, выброшенные операциями с итераторами или обменом элементов.
Сложность
Обозначим через \(\scriptsize N\)N std::distance(first, last):
Возможная реализация
template<class BidirIt>
bool prev_permutation(BidirIt first, BidirIt last)
{
if (first == last)
return false;
BidirIt i = last;
if (first == --i)
return false;
while (1)
{
BidirIt i1, i2;
i1 = i;
if (*i1 < *--i)
{
i2 = last;
while (!(*--i2 < *i))
;
std::iter_swap(i, i2);
std::reverse(i1, last);
return true;
}
if (i == first)
{
std::reverse(first, last);
return false;
}
}
}
|
Примечания
В среднем по всей последовательности перестановок типичные реализации выполняют около 3 сравнений и 1,5 обмена за вызов.
Реализации (например, MSVC STL) могут использовать векторизацию, если тип итератора удовлетворяет требованиям LegacyContiguousIterator, а обмен значениями его типа не вызывает ни одной нетривиальной специальной функции-члена или найденной через ADL функции swap.
Пример
Следующий код выводит все шесть перестановок строки "cab" в обратном порядке.
#include <algorithm>
#include <iostream>
#include <string>
int main()
{
std::string s = "cab";
do
{
std::cout << s << ' ';
}
while (std::prev_permutation(s.begin(), s.end()));
std::cout << s << '\n';
}
Вывод:
cab bca bac acb abc cba
См. также
|
(C++11) | определяет, является ли одна последовательность перестановкой другой последовательности (шаблон функции и объект-функция алгоритма) |
|
(C++20) | |
| генерирует следующую по возрастанию лексикографическую перестановку диапазона элементов (шаблон функции и объект-функция алгоритма) |
|
|
(C++20) | |
|
(C++20) | генерирует следующую по убыванию лексикографическую перестановку диапазона элементов (объект-функция алгоритма) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/algorithm/prev_permutation