std::unique
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, |
(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 > |
(4) | (desde C++17) |
Elimina todos los elementos excepto el primero de cada grupo consecutivo de elementos equivalentes del rango [
first,
last)
y devuelve un iterador posterior al final para el nuevo final del rango.
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
[
first,
last)
no se acorta con la operación de eliminación. Dado result como el iterador devuelto:
- Todos los iteradores en
[
result,
last)
siguen siendo desreferenciables.
- Todos los iteradores en
|
(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) |
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):
[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) | |
Crea una copia de un rango de elementos que no contiene duplicados consecutivos. (plantilla de función) | |
Elimina elementos que satisfacen un criterio específico. (plantilla de función) | |
Elimina elementos consecutivos duplicados. (función miembro pública de std::list )
| |
(C++11) |
Elimina elementos consecutivos duplicados. (función miembro pública de std::forward_list )
|
(C++20) |
Elimina elementos duplicados consecutivos en un rango. (niebloid) |