Espacios de nombres
Variantes
Acciones

std::unique

De cppreference.com
< cpp‎ | algorithm
 
 
Biblioteca de algoritmos
Políticas de ejecución (C++17)
Operaciones de secuencia no modificantes
(C++11)(C++11)(C++11)
(C++17)
Operaciones de secuencia modificantes
Operaciones en almacenamiento no inicializado
Operaciones de partición
Operaciones de ordenación
(C++11)
Operaciones de búsqueda binaria
Operaciones de conjuntos (en rangos ordenados)
Operaciones de pila
(C++11)
Operaciones mínimo/máximo
(C++11)
(C++17)
Permutaciones
Operaciones numéricas
Bibliotecas C
 
Definido en el archivo de encabezado <algorithm>
template< class ForwardIt >
ForwardIt unique( ForwardIt first, ForwardIt last );
(1) (constexpr desde C++20)
template< class ExecutionPolicy, class ForwardIt >

ForwardIt unique( ExecutionPolicy&& policy,

                  ForwardIt first, ForwardIt last );
(2) (desde C++17)
template< class ForwardIt, class BinaryPred >
ForwardIt unique( ForwardIt first, ForwardIt last, BinaryPred p );
(3) (constexpr desde C++20)
template< class ExecutionPolicy,

          class ForwardIt, class BinaryPred >
ForwardIt unique( ExecutionPolicy&& policy,

                  ForwardIt first, ForwardIt last, BinaryPred p );
(4) (desde C++17)

Elimina todos los elementos excepto el primero de cada grupo consecutivo de elementos equivalentes del rango [firstlast) y devuelve un iterador posterior al final para el nuevo final del rango.

1) Los elementos se comparan utilizando operator==.
Si operator== no establece una relación de equivalencia, el comportamiento no está definido.
3) Los elementos se comparan utilizando el predicado binario dado p.
Si p no establece una relación de equivalencia, el comportamiento no está definido.
2,4) Igual que (1,3), pero ejecutado de acuerdo con policy.
Estas sobrecargas no participan en la resolución de sobrecarga a menos que std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> (hasta C++20) std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>> (desde C++20) sea verdadera.

Contenido

[editar] Explicación

La eliminación se realiza desplazando los elementos en el rango de tal manera que los elementos que no se deben eliminar aparezcan al principio del rango.

  • El desplazamiento se realiza mediante la asignación de copia (hasta C++11)asignación de movimiento (desde C++11).
  • La operación de eliminación es estable: el orden relativo de los elementos que no se deben eliminar permanece igual.
  • La secuencia subyacente de [firstlast) no se acorta con la operación de eliminación. Dado result como el iterador devuelto:
  • Cada elemento de [resultlast) tiene un estado válido pero no especificado, porque la asignación de movimiento puede eliminar elementos al moverse desde elementos que originalmente estaban en ese rango.
(desde C++11)

[editar] Parámetros

first, last - El rango de elementos a procesar.
policy - La política de ejecución a usar. Véase política de ejecución para más detalles.
p - Predicado binario que devuelve ​true si los elementos deben tratarse como iguales.

La signatura de la función predicado deberá ser equivalente a la siguiente:

 bool pred(const Tipo1 &a, const Tipo2 &b);

Mientras que la signatura no necesita tener const &, la función no debe modificar los objetos que se le han pasado y debe ser capaz de aceptar todos los valores de tipo (posiblemente const) Tipo1 y Tipo2 independientemente de la categoría de valor (por lo tanto, no se permite Tipo1 &, ni Tipo1 a menos que para Tipo1 un movimiento sea equivalente a una copia (desde C++11)).
Los tipos Tipo1 y Tipo2 deben ser tales que un objeto de tipo ForwardIt puede ser desreferenciado y luego convertido implícitamente a ambos. ​

Requisitos de tipo
-
ForwardIt debe satisfacer los requisitos de ForwardIterator.
-
El tipo del ForwardIt desreferenciado debe cumplir con los requisitos de AsignablePorMovimiento.

[editar] Return value

Un ForwardIt al nuevo final del rango.

[editar] Complexity

Dada N as std::distance(first, last):

1,2) Exactamente max(0,N-1) comparaciones usando operator==.
3,4) Exactamente max(0,N-1) aplicaciones del predicado p.

[editar] Excepciones

Las sobrecargas con un parámetro de plantilla llamado ExecutionPolicy (política de ejecución) reportan errores tales que:

  • Si la ejecución de una función invocada como parte del algoritmo lanza una excepción y la política de ejecución es una de las tres políticas estándar, se llama a std::terminate. Para cualquier otra política de ejecución, el comportamiento está definido por la implementación.
  • Si el algoritmo falla al asignar memoria, se lanza std::bad_alloc.

[editar] Posible implementación

Véanse también las implementaciones en libstdc++, libc++, y MSVC STL.

unique (1)
template<class ForwardIt>
ForwardIt unique(ForwardIt first, ForwardIt last)
{
    if (first == last)
        return last;
 
    ForwardIt result = first;
    while (++first != last)
        if (!(*result == *first) && ++result != first)
            *result = std::move(*first);
 
    return ++result;
}
unique (3)
template<class ForwardIt, class BinaryPredicate>
ForwardIt unique(ForwardIt first, ForwardIt last, BinaryPredicate p)
{
    if (first == last)
        return last;
 
    ForwardIt result = first;
    while (++first != last)
        if (!p(*result, *first) && ++result != first)
            *result = std::move(*first);
 
    return ++result;
}

[editar] Notas

Una llamada a unique suele ir seguida de una llamada a la función miembro erase de un contenedor para eliminar elementos del contenedor.

[editar] Ejemplo

#include <algorithm>
#include <iostream>
#include <vector>
 
int main()
{
    // una vector que contiene varios elementos duplicados
    std::vector<int> v{1, 2, 1, 1, 3, 3, 3, 4, 5, 4};
    auto print = [&](int id)
    {
        std::cout << "@" << id << ": ";
        for (int i : v)
            std::cout << i << ' ';
        std::cout << '\n';
    };
    print(1);
 
    // eliminar duplicados consecutivos (adyacentes)
    auto last = std::unique(v.begin(), v.end());
    // v ahora alberga {1 2 1 3 4 5 4 x x x}, donde 'x' es indeterminada
    v.erase(last, v.end());
    print(2);
 
    // sort seguido de unique, para eliminar todos los duplicados
    std::sort(v.begin(), v.end()); // {1 1 2 3 4 4 5}
    print(3);
 
    last = std::unique(v.begin(), v.end());
    // v ahora alberga {1 2 3 4 5 x x}, donde 'x' es indeterminada
    v.erase(last, v.end());
    print(4);
}

Salida:

@1: 1 2 1 1 3 3 3 4 5 4
@2: 1 2 1 3 4 5 4
@3: 1 1 2 3 4 4 5
@4: 1 2 3 4 5

[editar] Informes de defectos

Los siguientes informes de defectos de cambio de comportamiento se aplicaron de manera retroactiva a los estándares de C++ publicados anteriormente.

ID Aplicado a Comportamiento según lo publicado Comportamiento correcto
LWG 202 C++98 El comportamiento no estaba claro si los elementos
se comparan utilizando una relación de no equivalencia,
El comportamiento no está definido en este caso.

[editar] Véase también

Encuentra dos elementos contiguos idénticos (o que satisfagan un predicado dado).
(plantilla de función) [editar]
Crea una copia de un rango de elementos que no contiene duplicados consecutivos.
(plantilla de función) [editar]
Elimina elementos que satisfacen un criterio específico.
(plantilla de función) [editar]
Elimina elementos consecutivos duplicados.
(función miembro pública de std::list) [editar]
(C++11)
Elimina elementos consecutivos duplicados.
(función miembro pública de std::forward_list) [editar]
Elimina elementos duplicados consecutivos en un rango.
(niebloid) [editar]