El modismo de borrar-eliminar es una técnica común de C++ para eliminar elementos que cumplen un criterio determinado de un contenedor de la biblioteca estándar de C++ . [ 1 ] [ 2 ] [ 3 ]
Motivación
Una tarea común de programación consiste en eliminar de una colección todos los elementos que tengan un valor determinado o cumplan un criterio específico . En C++, esto se puede lograr mediante un bucle escrito manualmente. Sin embargo, es preferible utilizar un algoritmo de la biblioteca estándar de C++ para este tipo de tareas. [ 1 ] [ 2 ] [ 3 ]
La función miembro erasese puede usar para eliminar un elemento de una colección, pero para contenedores basados en un array, como vector, todos los elementos posteriores al elemento eliminado deben moverse hacia adelante para evitar "huecos" en la colección. Llamar a erase varias veces en el mismo contenedor genera una sobrecarga considerable debido al movimiento de los elementos.
La algorithmbiblioteca proporciona los removealgoritmos remove_ifpara esto. Debido a que estos algoritmos operan sobre un rango de elementos denotado por dos iteradores hacia adelante, no tienen conocimiento del contenedor o colección subyacente. [ 1 ] [ 4 ]
Estos algoritmos no eliminan elementos del contenedor, sino que mueven al principio del rango todos aquellos que no cumplen con los criterios de eliminación, manteniendo el orden relativo de los elementos. Esto se realiza en una sola pasada por el rango de datos.
Como en realidad no se elimina ningún elemento y el contenedor conserva el mismo tamaño, la cola del array tiene una longitud igual al número de elementos "eliminados"; estos elementos permanecen en la memoria pero en un estado no especificado. removedevuelve un iterador que apunta al primero de estos elementos de la cola para que puedan eliminarse mediante una sola llamada a erase.
Hacer lo mismo utilizando solo eraseda como resultado tantas pasadas como elementos haya para eliminar. En cada una de estas pasadas, todos los elementos que están después del elemento eliminado deben moverse, lo que consume más tiempo que mover elementos en una sola pasada.
C++20
A partir de C++20 , las funciones libres std::erasey std::erase_ifse proporcionan para los contenedores STL. Estas funciones de conveniencia se pueden usar para realizar el borrado correcto de elementos sin que el programador tenga que usar explícitamente el modismo erase-remove. [ 5 ]
Limitación
El modismo de borrar-eliminar no se puede utilizar para contenedores que devuelven const_iterator(por ejemplo: set ) [ 6 ].
std::removey/o std::remove_ifno mantienen elementos que se eliminan (a diferencia de std::partition, std::stable_partition). Por lo tanto, erase-remove solo se puede usar con contenedores que contienen elementos con semántica de valor completo sin incurrir en fugas de recursos. [ 7 ]
Ejemplo
Explorador de compiladores
// Utilice g++ -std=c++11 o clang++ -std=c++11 para compilar.#include <algorithm> // remove y remove_if #include <iostream> #include <vector>void Imprimir ( const std :: vector < int >& vec ) { for ( auto val : vec ) { std :: cout << val << ' ' ; } std :: cout << '\n' ; }int main () { std :: vector < int > v = { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 }; Imprimir ( v );// Elimina todos los elementos con el valor 5. v . erase ( std :: remove ( v . begin (), v . end (), 5 ), v . end ()); Imprimir ( v );// Elimina todos los números impares. v . erase ( std :: remove_if ( v . begin (), v . end (), []( int val ) { return val & 1 ; }), v . end ()); Print ( v ); }/* Salida: 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 6 7 8 9 0 2 4 6 8 */Referencias
- 1 2 3 Meyers, Scott (2001). Effective STL: 50 Specific Ways to Improve Your Use of the Standard Template Library . Addison-Wesley.
- 1 2 Sutter, Herb ; Alexandrescu, Andrei (2004). Estándares de codificación de C++: 101 reglas, directrices y mejores prácticas . Addison-Wesley.
- 1 2 Scott Meyers, "Algoritmos STL frente a bucles escritos a mano", Dr. Dobbs , 25 de octubre de 2001.
- ↑ Josuttis, Nicolai (1999). Biblioteca estándar de C++: un tutorial y referencia . Addison-Wesley.
- ↑ "std::erase, std::erase_if (std::vector) - cppreference.com" . en.cppreference.com . Consultado el 9 de diciembre de 2021 .
- ↑ "Modismo de borrar-eliminar con std::set" . stackoverflow.com . Stack Overflow. 25 de septiembre de 2010. Consultado el 14 de abril de 2013 .
- ↑ Meyers, Scott (2001). Effective STL : 50 maneras específicas de mejorar el uso de la biblioteca de plantillas estándar . Boston: Addison-Wesley. pp. 143–145 . ISBN 0201749629OCLC 46713127
- C++
- Software programado en C++