Namespaces
Variants

std::ranges::is_permutation

De es.cppreference.net
 
 
Biblioteca de algoritmos
Algoritmos restringidos y algoritmos sobre rangos (C++20)
Algoritmos restringidos, por ejemplo, ranges::copy, ranges::sort, ...
Operaciones de secuencia no modificadoras    
Operaciones por lotes
(C++17)
Operaciones de búsqueda
Operaciones de secuencia modificadoras
Operaciones de copia
(C++11)
(C++11)
Operaciones de intercambio
Operaciones de transformación
Operaciones de generación
Operaciones de eliminación
Operaciones de cambio de orden
(hasta C++17)(C++11)
(C++20)(C++20)
Operaciones de muestreo
(C++17)

Operaciones de ordenamiento y relacionadas
Operaciones de particionado
(C++11)    

Operaciones de ordenamiento
Operaciones de búsqueda binaria
(en rangos particionados)
Operaciones de conjuntos (en rangos ordenados)
Operaciones de mezcla (en rangos ordenados)
Operaciones de montículo (heap)
Operaciones de mínimo/máximo
(C++11)
(C++17)
Operaciones de comparación lexicográfica
Operaciones de permutación


 
Algoritmos restringidos
Todos los nombres en este menú pertenecen al espacio de nombres std::ranges
Operaciones de secuencia no modificadoras
Operaciones de secuencia modificadoras
Operaciones de particionado
Operaciones de ordenamiento
Operaciones de búsqueda binaria (en rangos ordenados)
       
       
Operaciones de conjuntos (en rangos ordenados)
Operaciones de montículo
Operaciones de mínimo/máximo
       
       
Operaciones de permutación
Operaciones de plegado
Operaciones en almacenamiento no inicializado
Tipos de retorno
 
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 igual a [first2, last2) (después de la aplicación de las proyecciones correspondientes Proj1, Proj2, y usando el predicado binario Pred como comparador). En caso contrario, devuelve false.
2) Igual que (1), pero usa r1 como el primer rango fuente y r2 como el segundo rango fuente, como si 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 objetos función de algoritmo (informalmente conocidos como niebloids), es decir:

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 & objeto función de algoritmo)
genera la siguiente permutación lexicográfica menor de un rango de elementos
(plantilla de función & objeto función de algoritmo)
especifica que una relación impone una relación de equivalencia
(concepto)