Namespaces
Variants

std:: is_permutation

From cppreference.net
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy , ranges::sort , ...
Execution policies (C++17)
Non-modifying sequence operations
Batch operations
(C++17)
Search operations
Modifying sequence operations
Copy operations
(C++11)
(C++11)
Swap operations
Transformation operations
Generation operations
Removing operations
Order-changing operations
(until C++17) (C++11)
(C++20) (C++20)
Sampling operations
(C++17)

Sorting and related operations
Partitioning operations
Sorting operations
Binary search operations
(on partitioned ranges)
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Lexicographical comparison operations
Permutation operations
is_permutation
(C++11)


C library
Numeric operations
Operations on uninitialized memory
Определено в заголовке <algorithm>
template < class ForwardIt1, class ForwardIt2 >

bool is_permutation ( ForwardIt1 first1, ForwardIt1 last1,

ForwardIt2 first2 ) ;
(1) (начиная с C++11)
(constexpr начиная с C++20)
template < class ForwardIt1, class ForwardIt2,

class BinaryPredicate >
bool is_permutation ( ForwardIt1 first1, ForwardIt1 last1,

ForwardIt2 first2, BinaryPredicate p ) ;
(2) (начиная с C++11)
(constexpr начиная с C++20)
template < class ForwardIt1, class ForwardIt2 >

bool is_permutation ( ForwardIt1 first1, ForwardIt1 last1,

ForwardIt2 first2, ForwardIt2 last2 ) ;
(3) (начиная с C++14)
(constexpr начиная с C++20)
template < class ForwardIt1, class ForwardIt2,

class BinaryPredicate >
bool is_permutation ( ForwardIt1 first1, ForwardIt1 last1,
ForwardIt2 first2, ForwardIt2 last2,

BinaryPredicate p ) ;
(4) (начиная с C++14)
(constexpr начиная с C++20)

Проверяет, является ли [ first1 , last1 ) перестановкой диапазона, начинающегося с first2 :

  • Для перегрузок (1,2) второй диапазон содержит std:: distance ( first1, last1 ) элементов.
  • Для перегрузок (3,4) второй диапазон представляет собой [ first2 , last2 ) .
1,3) Элементы сравниваются с использованием operator == .
2,4) Элементы сравниваются с использованием заданного бинарного предиката p .

Если ForwardIt1 и ForwardIt2 имеют различные типы значений , программа является некорректной.

Если функция сравнения не является отношением эквивалентности , поведение не определено.

Содержание

Параметры

first1, last1 - пара итераторов, определяющих первый диапазон элементов для сравнения
first2, last2 - пара итераторов, определяющих второй диапазон элементов для сравнения
p - бинарный предикат, который возвращает ​ true если элементы следует считать равными.

Сигнатура функции-предиката должна быть эквивалентна следующей:

bool pred ( const Type1 & a, const Type2 & b ) ;

Хотя сигнатура не обязана иметь const & , функция не должна модифицировать передаваемые ей объекты и должна быть способна принимать все значения типа (возможно, const) Type1 и Type2 независимо от категории значения (следовательно, Type1 & не допускается , как и Type1 , если для Type1 перемещение не эквивалентно копированию (начиная с C++11) ).
Типы Type1 и Type2 должны быть такими, чтобы объекты типов InputIt1 и InputIt2 могли быть разыменованы и затем неявно преобразованы в Type1 и Type2 соответственно. ​

Требования к типам
-
ForwardIt1, ForwardIt2 должны удовлетворять требованиям LegacyForwardIterator .

Возвращаемое значение

true если диапазон [ first1 , last1 ) является перестановкой диапазона [ first2 , last2 ) , false в противном случае.

Сложность

Дано N как std:: distance ( first1, last1 ) :

1) Ровно N сравнений с использованием operator == если диапазоны равны, в противном случае O(N 2
)
сравнений в худшем случае.
2) Ровно N применений предиката p если диапазоны равны, в противном случае O(N 2
)
применений в худшем случае.
3,4) Если ForwardIt1 и ForwardIt2 оба являются LegacyRandomAccessIterator , и last1 - first1 ! = last2 - first2 равно true , никаких сравнений произведено не будет.
В противном случае:
3) Ровно N сравнений с использованием operator == если два диапазона равны, в противном случае O(N 2
)
сравнений в худшем случае.
4) Ровно N применений предиката p если два диапазона равны, в противном случае O(N 2
)
применений в худшем случае.

Возможная реализация

template<class ForwardIt1, class ForwardIt2>
bool is_permutation(ForwardIt1 first, ForwardIt1 last,
                    ForwardIt2 d_first)
{
    // пропустить общий префикс
    std::tie(first, d_first) = std::mismatch(first, last, d_first);
    // перебрать оставшуюся часть, подсчитывая, сколько раз каждый элемент
    // из [first, last) встречается в [d_first, d_last)
    if (first != last)
    {
        ForwardIt2 d_last = std::next(d_first, std::distance(first, last));
        for (ForwardIt1 i = first; i != last; ++i)
        {
            if (i != std::find(first, i, *i))
                continue; // этот *i уже был проверен
            auto m = std::count(d_first, d_last, *i);
            if (m == 0 || std::count(i, last, *i) != m)
                return false;
        }
    }
    return true;
}

Примечание

Функция std::is_permutation может использоваться в тестировании , а именно для проверки корректности алгоритмов перестановки (например, сортировки, перемешивания, разделения). Если x является исходным диапазоном и y является переставленным диапазоном, то std :: is_permutation ( x, y ) == true означает, что y состоит из "тех же" элементов, возможно находящихся на других позициях.

Пример

#include <algorithm>
#include <iostream>
template<typename Os, typename V>
Os& operator<<(Os& os, const V& v)
{
    os << "{ ";
    for (const auto& e : v)
        os << e << ' ';
    return os << '}';
}
int main()
{
    static constexpr auto v1 = {1, 2, 3, 4, 5};
    static constexpr auto v2 = {3, 5, 4, 1, 2};
    static constexpr auto v3 = {3, 5, 4, 1, 1};
    std::cout << v2 << " is a permutation of " << v1 << ": " << std::boolalpha
              << std::is_permutation(v1.begin(), v1.end(), v2.begin()) << '\n'
              << v3 << " is a permutation of " << v1 << ": "
              << std::is_permutation(v1.begin(), v1.end(), v3.begin()) << '\n';
}

Вывод:

{ 3 5 4 1 2 } is a permutation of { 1 2 3 4 5 }: true
{ 3 5 4 1 1 } is a permutation of { 1 2 3 4 5 }: false

Смотрите также

генерирует следующую большую лексикографическую перестановку диапазона элементов
(шаблон функции)
генерирует следующую меньшую лексикографическую перестановку диапазона элементов
(шаблон функции)
указывает, что relation накладывает отношение эквивалентности
(концепт)
определяет, является ли последовательность перестановкой другой последовательности
(функциональный объект алгоритма)