2011-12-13 14 views
20

¿Cómo puedo eliminar el último miembro de un conjunto?Borrar el miembro final de std :: set

Por ejemplo:

set<int> setInt; 
setInt.insert(1); 
setInt.insert(4); 
setInt.insert(3); 
setInt.insert(2); 

¿Cómo puedo eliminar 4 de setInt? Intenté algo como:

setInt.erase(setInt.rbegin()); 

pero recibí un error.

+0

Doh, tienes razón, olvidé que el conjunto no tiene un iterador de acceso aleatorio. Use 'setInt.erase (std :: prev (setInt.end()));' – AJG85

Respuesta

17
if (!setInt.empty()) { 
    std::set<int>::iterator it = setInt.end(); 
    --it; 
    setInt.erase(it); 
} 

Por cierto, si está haciendo esto mucho (añadiendo cosas a un conjunto en orden arbitrario y luego retirar el elemento superior), que podría también echar un vistazo a std::priority_queue, ver si que se adapte a su uso.

+0

Oh, whoops, pensé que 'if' era un bucle' for' por alguna razón ... –

30

en C++ 11

setInt.erase(std::prev(setInt.end())); 

Puede decidir cómo desea manejar los casos en que el conjunto está vacío.

1

Si desea eliminar 4 en lugar de la última, debe usar el método de búsqueda. Según el caso de uso 4 puede que no sea el último.

std::set<int>::iterator it = setInt.find(4); 
if(it != setInt.end()) { 
    setInt.erase(it); 
} 

Si desea borrar el último elemento de uso:.

if (!setInt.empty()) { 
    setInt.erase(--setInt.rbegin().base()); 
    // line above is equal to 
    // setInt.erase(--setInt.end()); 
} 

Aunque no estaba segura de si - * Final(); es O.K. Leí algo de lectura. Entonces, - en rbegin(). Base() conduce al mismo resultado que - al final(). Y ambos deberían funcionar.

+0

setInt. [Rend() ] (http://www.cplusplus.com/reference/stl/set/rend/) devuelve un iterador que apunta antes de setInt.begin(), por lo que no tiene nada que ver con el final del conjunto. – wigy

+0

tienes razón al intentar escribir. :-(Soluciono esto – Totonga

+1

¿En qué se diferencia su propuesta de la de la pregunta, que como ya sabemos no funciona? – bitmask

0

Compruebe si el conjunto está vacío o no. De lo contrario, obtenga el último elemento y configúrelo como iterador, reduzca ese iterador y borre el último elemento.

if (!setInt.empty()) 
{ 
    std::set<int>::iterator it = setInt.end(); 
    --it; 
    if(it != setInt.end()) { 
    setInt.erase(it); 
    } 
} 
5

Me propongo utilizar un nombre diferente para rbegin que tiene un tipo adecuado:

setInt.erase(--setInt.end()); 

Suponiendo que usted marcó setInt no está vacío!

BTW. esto funciona porque puede llamar al operador de disminución de mutación de forma temporal (del tipo std::set<int>::iterator). Este temporal se pasará a la función de borrado.

+0

Astucia, porque a diferencia de 'std :: vector :: iterator', no hay forma de que 'std :: set :: iterator' pueda ser un puntero. Debe ser un tipo de clase, por lo que los temporales deben ser decrementables. –

+0

@SteveJessop: Ellos son :) – bitmask

Cuestiones relacionadas