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
Definido en el encabezado <algorithm>
template < class ForwardIt1, class ForwardIt2 >

bool is_permutation ( ForwardIt1 first1, ForwardIt1 last1,

ForwardIt2 first2 ) ;
(1) (desde C++11)
(constexpr desde C++20)
template < class ForwardIt1, class ForwardIt2,

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

ForwardIt2 first2, BinaryPredicate p ) ;
(2) (desde C++11)
(constexpr desde C++20)
template < class ForwardIt1, class ForwardIt2 >

bool is_permutation ( ForwardIt1 first1, ForwardIt1 last1,

ForwardIt2 first2, ForwardIt2 last2 ) ;
(3) (desde C++14)
(constexpr desde C++20)
template < class ForwardIt1, class ForwardIt2,

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

BinaryPredicate p ) ;
(4) (desde C++14)
(constexpr desde C++20)

Comprueba si [ first1 , last1 ) es una permutación de un rango que comienza en first2 :

  • Para las sobrecargas (1,2) , el segundo rango tiene std:: distance ( first1, last1 ) elementos.
  • Para las sobrecargas (3,4) , el segundo rango es [ first2 , last2 ) .
1,3) Los elementos se comparan utilizando operator == .
2,4) Los elementos se comparan utilizando el predicado binario dado p .

Si ForwardIt1 y ForwardIt2 tienen diferentes tipos de valor , el programa está mal formado.

Si la función de comparación no es una relación de equivalencia , el comportamiento es indefinido.

Contenidos

Parámetros

first1, last1 - el par de iteradores que define el primer rango de elementos a comparar
first2, last2 - el par de iteradores que define el segundo rango de elementos a comparar
p - predicado binario que devuelve ​ true si los elementos deben tratarse como iguales.

La firma de la función predicado debe ser equivalente a la siguiente:

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

Aunque la firma no necesita tener const & , la función no debe modificar los objetos pasados a ella y debe poder aceptar todos los valores de tipo (posiblemente const) Type1 y Type2 independientemente de la categoría de valor (por lo tanto, Type1 & no está permitido , ni tampoco Type1 a menos que para Type1 un movimiento sea equivalente a una copia (desde C++11) ).
Los tipos Type1 y Type2 deben ser tales que los objetos de tipos InputIt1 y InputIt2 puedan ser desreferenciados y luego convertidos implícitamente a Type1 y Type2 respectivamente. ​

Requisitos de tipo
-
ForwardIt1, ForwardIt2 deben cumplir con los requisitos de LegacyForwardIterator .

Valor de retorno

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

Complejidad

Dado N como std:: distance ( first1, last1 ) :

1) Exactamente N comparaciones usando operator == si los dos rangos son iguales, de lo contrario O(N 2
)
comparaciones en el peor caso.
2) Exactamente N aplicaciones del predicado p si los dos rangos son iguales, de lo contrario O(N 2
)
aplicaciones en el peor caso.
3,4) Si ForwardIt1 y ForwardIt2 son ambos LegacyRandomAccessIterator , y last1 - first1 ! = last2 - first2 es true , no se realizará ninguna comparación.
De lo contrario:
3) Exactamente N comparaciones usando operator == si los dos rangos son iguales, de lo contrario O(N 2
)
comparaciones en el peor caso.
4) Exactamente N aplicaciones del predicado p si los dos rangos son iguales, de lo contrario O(N 2
)
aplicaciones en el peor caso.

Implementación posible

template<class ForwardIt1, class ForwardIt2>
bool is_permutation(ForwardIt1 first, ForwardIt1 last,
                    ForwardIt2 d_first)
{
    // omitir prefijo común
    std::tie(first, d_first) = std::mismatch(first, last, d_first);
    // iterar sobre el resto, contando cuántas veces aparece cada elemento
    // de [first, last) en [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; // este *i ya ha sido verificado
            auto m = std::count(d_first, d_last, *i);
            if (m == 0 || std::count(i, last, *i) != m)
                return false;
        }
    }
    return true;
}

Nota

La función std::is_permutation puede utilizarse en testing , concretamente para verificar la corrección de algoritmos de reordenamiento (por ejemplo, ordenación, mezcla, partición). Si x es un rango original y y es un rango permutado entonces std :: is_permutation ( x, y ) == true significa que y contiene "los mismos" elementos, posiblemente en posiciones diferentes.

Ejemplo

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

Salida:

{ 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

Véase tambié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)
determina si una secuencia es una permutación de otra secuencia
(objeto función de algoritmo)