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
Definido en el encabezado <algorithm>
Firma de llamada
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) (desde 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) (desde C++20)
1) Devuelve true si existe una permutación de los elementos en el rango [ first1 , last1 ) que hace que el rango sea igual a [ first2 , last2 ) (después de aplicar las proyecciones correspondientes Proj1 , Proj2 , y usando el predicado binario Pred como comparador). De lo contrario devuelve false .
2) Igual que (1) , pero utiliza r1 como el primer rango fuente y r2 como el segundo rango fuente, como si se usara ranges:: begin ( r1 ) como first1 , ranges:: end ( r1 ) como last1 , ranges:: begin ( r2 ) como first2 , y ranges:: end ( r2 ) como last2 .

Las entidades similares a funciones descritas en esta página son algorithm function objects (conocidas informalmente como niebloids ), es decir:

Contenidos

Parámetros

first1, last1 - el par iterador-sentinel que define el primer rango de elementos
first2, last2 - el par iterador-sentinel que define el segundo rango de elementos
r1 - el primer range de los elementos
r2 - el segundo range de los elementos
pred - predicado a aplicar a los elementos proyectados
proj1 - proyección a aplicar a los elementos en el primer rango
proj2 - proyección a aplicar a los elementos en el segundo rango

Valor de retorno

true si el rango [ first1 , last1 ) es una permutación del rango [ first2 , last2 ) .

Complejidad

Como máximo O(N 2 ) aplicaciones del predicado y cada proyección, o exactamente N si las secuencias ya son iguales, donde N es ranges:: distance ( first1, last1 ) . Sin embargo, si ranges:: distance ( first1, last1 ) ! = ranges:: distance ( first2, last2 ) , no se realizan aplicaciones del predicado ni de las proyecciones.

Notas

La permutación es una relación de equivalencia .

La función ranges::is_permutation puede utilizarse en pruebas, por ejemplo para verificar la corrección de algoritmos de reordenamiento como ordenación, mezcla, particionado. Si p es una secuencia original y q es una secuencia "mutada", entonces ranges :: is_permutation ( p, q ) == true significa que q contiene "los mismos" elementos (posiblemente permutados) que p .

Implementación posible

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
    {
        // omitir prefijo común
        auto ret = std::ranges::mismatch(first1, last1, first2, last2,
                                         std::ref(pred), std::ref(proj1), std::ref(proj2));
        first1 = ret.in1, first2 = ret.in2;
        // iterar sobre el resto, contando cuántas veces aparece cada elemento
        // desde [first1, last1) aparece en [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; // este *i ha sido verificado
            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 {};

Ejemplo

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

Salida:

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

Véase también

genera la siguiente permutación lexicográfica mayor de un rango de elementos
(objeto función de algoritmo)
genera la siguiente permutación lexicográfica menor de un rango de elementos
(objeto función de algoritmo)
determina si una secuencia es una permutación de otra secuencia
(plantilla de función)
genera la siguiente permutación lexicográfica mayor de un rango de elementos
(plantilla de función)
genera la siguiente permutación lexicográfica menor de un rango de elementos
(plantilla de función)
especifica que una relation impone una relación de equivalencia
(concepto)