Namespaces
Variants

std::ranges:: 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
C library
Numeric operations
Operations on uninitialized memory
Constrained algorithms
All names in this menu belong to namespace std::ranges
Non-modifying sequence operations
Modifying sequence operations
Partitioning operations
Sorting operations
Binary search operations (on sorted ranges)
Set operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Permutation operations
Fold operations
Operations on uninitialized storage
Return types
Défini dans l'en-tête <algorithm>
Signature d'appel
template < std:: forward_iterator I1, std:: sentinel_for < I1 > S1,

std:: forward_iterator I2, std:: sentinel_for < I2 > S2,
class Proj1 = std:: identity , class Proj2 = std:: identity ,
std:: indirect_equivalence_relation < std :: projected < I1, Proj1 > ,
std :: projected < I2, Proj2 >>
Pred = ranges:: equal_to >
constexpr bool
is_permutation ( I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = { } ,

Proj1 proj1 = { } , Proj2 proj2 = { } ) ;
(1) (depuis C++20)
template < ranges:: forward_range R1, ranges:: forward_range R2,

class Proj1 = std:: identity , class Proj2 = std:: identity ,
std:: indirect_equivalence_relation <
std :: projected < ranges:: iterator_t < R1 > , Proj1 > ,
std :: projected < ranges:: iterator_t < R2 > , Proj2 >>
Pred = ranges:: equal_to >
constexpr bool
is_permutation ( R1 && r1, R2 && r2, Pred pred = { } ,

Proj1 proj1 = { } , Proj2 proj2 = { } ) ;
(2) (depuis C++20)
1) Retourne true s'il existe une permutation des éléments dans l'intervalle [ first1 , last1 ) qui rend l'intervalle égal à [ first2 , last2 ) (après application des projections correspondantes Proj1 , Proj2 , et en utilisant le prédicat binaire Pred comme comparateur). Sinon retourne false .
2) Identique à (1) , mais utilise r1 comme première plage source et r2 comme seconde plage source, comme si on utilisait ranges:: begin ( r1 ) comme first1 , ranges:: end ( r1 ) comme last1 , ranges:: begin ( r2 ) comme first2 , et ranges:: end ( r2 ) comme last2 .

Les entités de type fonction décrites sur cette page sont des objets fonction d'algorithmes (informellement appelés niebloids ), c'est-à-dire :

Table des matières

Paramètres

first1, last1 - la paire itérateur-sentinelle définissant la première plage d'éléments
first2, last2 - la paire itérateur-sentinelle définissant la seconde plage d'éléments
r1 - la première range des éléments
r2 - la seconde range des éléments
pred - prédicat à appliquer aux éléments projetés
proj1 - projection à appliquer aux éléments de la première plage
proj2 - projection à appliquer aux éléments de la seconde plage

Valeur de retour

true si la plage [ first1 , last1 ) est une permutation de la plage [ first2 , last2 ) .

Complexité

Au plus O(N 2 ) applications du prédicat et de chaque projection, ou exactement N si les séquences sont déjà égales, où N est ranges:: distance ( first1, last1 ) . Cependant si ranges:: distance ( first1, last1 ) ! = ranges:: distance ( first2, last2 ) , aucune application du prédicat et des projections n'est effectuée.

Notes

La permutation est une relation d'équivalence .

La ranges::is_permutation peut être utilisée dans les tests, par exemple pour vérifier l'exactitude des algorithmes de réarrangement tels que le tri, le mélange, la partition. Si p est une séquence originale et q est une séquence "mutée", alors ranges :: is_permutation ( p, q ) == true signifie que q est constituée des "mêmes" éléments (éventuellement permutés) que p .

Implémentation possible

struct is_permutation_fn
{
    template<std::forward_iterator I1, std::sentinel_for<I1> S1,
             std::forward_iterator I2, std::sentinel_for<I2> S2,
             class Proj1 = std::identity, class Proj2 = std::identity,
             std::indirect_equivalence_relation<std::projected<I1, Proj1>,
                                                std::projected<I2, Proj2>>
                                                    Pred = ranges::equal_to>
    constexpr bool operator()(I1 first1, S1 last1, I2 first2, S2 last2,
                              Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const
    {
        // ignorer le préfixe commun
        auto ret = std::ranges::mismatch(first1, last1, first2, last2,
                                         std::ref(pred), std::ref(proj1), std::ref(proj2));
        first1 = ret.in1, first2 = ret.in2;
        // itérer sur le reste, en comptant combien de fois chaque élément
        // de [first1, last1) apparaît dans [first2, last2)
        for (auto i {first1}; i != last1; ++i)
        {
            const auto i_proj {std::invoke(proj1, *i)};
            auto i_cmp = [&]<typename T>(T&& t)
            { 
                return std::invoke(pred, i_proj, std::forward<T>(t));
            };
            if (i != ranges::find_if(first1, i, i_cmp, proj1))
                continue; // ce *i a été vérifié
            if (const auto m {ranges::count_if(first2, last2, i_cmp, proj2)};
                m == 0 or m != ranges::count_if(i, last1, i_cmp, proj1))
                return false;
        }
        return true;
    }
    template<ranges::forward_range R1, ranges::forward_range R2,
             class Proj1 = std::identity, class Proj2 = std::identity,
             std::indirect_equivalence_relation<
                 std::projected<ranges::iterator_t<R1>, Proj1>,
                 std::projected<ranges::iterator_t<R2>, Proj2>>
                     Pred = ranges::equal_to>
    constexpr bool operator()(R1&& r1, R2&& r2, Pred pred = {},
                              Proj1 proj1 = {}, Proj2 proj2 = {}) const
    {
        return (*this)(ranges::begin(r1), ranges::end(r1),
                       ranges::begin(r2), ranges::end(r2),
                       std::move(pred), std::move(proj1), std::move(proj2));
    }
};
inline constexpr is_permutation_fn is_permutation {};

Exemple

#include <algorithm>
#include <array>
#include <cmath>
#include <iostream>
#include <ranges>
auto& operator<<(auto& os, std::ranges::forward_range auto const& v)
{
    os << "{ ";
    for (const auto& e : v)
        os << e << ' ';
    return os << "}";
}
int main()
{
    static constexpr auto r1 = {1, 2, 3, 4, 5};
    static constexpr auto r2 = {3, 5, 4, 1, 2};
    static constexpr auto r3 = {3, 5, 4, 1, 1};
    static_assert(
        std::ranges::is_permutation(r1, r1) &&
        std::ranges::is_permutation(r1, r2) &&
        std::ranges::is_permutation(r2, r1) &&
        std::ranges::is_permutation(r1.begin(), r1.end(), r2.begin(), r2.end()));
    std::cout
        << std::boolalpha
        << "is_permutation(" << r1 << ", " << r2 << "): "
        << std::ranges::is_permutation(r1, r2) << '\n'
        << "is_permutation(" << r1 << ", " << r3 << "): "
        << std::ranges::is_permutation(r1, r3) << '\n'
        << "is_permutation with custom predicate and projections: "
        << std::ranges::is_permutation(
            std::array {-14, -11, -13, -15, -12},  // 1st range
            std::array {'F', 'E', 'C', 'B', 'D'},  // 2nd range
            [](int x, int y) { return abs(x) == abs(y); }, // predicate
            [](int x) { return x + 10; },          // projection for 1st range
            [](char y) { return int(y - 'A'); })   // projection for 2nd range
        << '\n';
}

Sortie :

is_permutation({ 1 2 3 4 5 }, { 3 5 4 1 2 }): true
is_permutation({ 1 2 3 4 5 }, { 3 5 4 1 1 }): false
is_permutation with custom predicate and projections: true

Voir aussi

génère la prochaine permutation lexicographique supérieure d'une plage d'éléments
(objet fonction algorithme)
génère la prochaine permutation lexicographique inférieure d'une plage d'éléments
(objet fonction algorithme)
détermine si une séquence est une permutation d'une autre séquence
(modèle de fonction)
génère la prochaine permutation lexicographique supérieure d'une plage d'éléments
(modèle de fonction)
génère la prochaine permutation lexicographique inférieure d'une plage d'éléments
(modèle de fonction)
spécifie qu'une relation impose une relation d'équivalence
(concept)