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
Definiert im Header <algorithm>
Aufrufsignatur
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) (seit 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) (seit C++20)
1) Gibt true zurück, falls eine Permutation der Elemente im Bereich [ first1 , last1 ) existiert, die den Bereich gleich zu [ first2 , last2 ) macht (nach Anwendung der entsprechenden Projektionen Proj1 , Proj2 und unter Verwendung des binären Prädikats Pred als Komparator). Andernfalls wird false zurückgegeben.
2) Gleich wie (1) , verwendet jedoch r1 als ersten Quellbereich und r2 als zweiten Quellbereich, als ob ranges:: begin ( r1 ) als first1 , ranges:: end ( r1 ) als last1 , ranges:: begin ( r2 ) als first2 , und ranges:: end ( r2 ) als last2 verwendet würde.

Die auf dieser Seite beschriebenen funktionsähnlichen Entitäten sind Algorithm Function Objects (informell bekannt als Niebloids ), das heißt:

Inhaltsverzeichnis

Parameter

first1, last1 - das Iterator-Sentinel-Paar, das den ersten Bereich von Elementen definiert
first2, last2 - das Iterator-Sentinel-Paar, das den zweiten Bereich von Elementen definiert
r1 - der erste range der Elemente
r2 - der zweite range der Elemente
pred - Prädikat, das auf die projizierten Elemente angewendet wird
proj1 - Projektion, die auf die Elemente im ersten Bereich angewendet wird
proj2 - Projektion, die auf die Elemente im zweiten Bereich angewendet wird

Rückgabewert

true falls der Bereich [ first1 , last1 ) eine Permutation des Bereichs [ first2 , last2 ) ist.

Komplexität

Höchstens O(N 2 ) Anwendungen des Prädikats und jeder Projektion, oder genau N falls die Sequenzen bereits gleich sind, wobei N ist ranges:: distance ( first1, last1 ) . Allerdings falls ranges:: distance ( first1, last1 ) ! = ranges:: distance ( first2, last2 ) , werden keine Anwendungen des Prädikats und der Projektionen durchgeführt.

Hinweise

Die Permutation -Relation ist eine Äquivalenzrelation .

Die ranges::is_permutation kann im Testing verwendet werden, z.B. um die Korrektheit von umordnenden Algorithmen wie Sortieren, Mischen, Partitionieren zu überprüfen. Wenn p eine ursprüngliche Sequenz ist und q eine "mutierte" Sequenz, dann bedeutet ranges :: is_permutation ( p, q ) == true , dass q aus "denselben" Elementen (möglicherweise permutiert) besteht wie p .

Mögliche Implementierung

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
    {
        // gemeinsamen Präfix überspringen
        auto ret = std::ranges::mismatch(first1, last1, first2, last2,
                                         std::ref(pred), std::ref(proj1), std::ref(proj2));
        first1 = ret.in1, first2 = ret.in2;
        // über den Rest iterieren, zählen wie oft jedes Element vorkommt
        // aus [first1, last1) erscheint in [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; // dieser *i wurde geprüft
            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 {};

Beispiel

#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';
}

Ausgabe:

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

Siehe auch

erzeugt die nächstgrößere lexikografische Permutation eines Elementbereichs
(Algorithmus-Funktionsobjekt)
erzeugt die nächstkleinere lexikografische Permutation eines Elementbereichs
(Algorithmus-Funktionsobjekt)
bestimmt, ob eine Sequenz eine Permutation einer anderen Sequenz ist
(Funktionstemplate)
erzeugt die nächstgrößere lexikografische Permutation eines Elementbereichs
(Funktionstemplate)
erzeugt die nächstkleinere lexikografische Permutation eines Elementbereichs
(Funktionstemplate)
spezifiziert, dass eine relation eine Äquivalenzrelation definiert
(Konzept)