2011-01-24 11 views
13
std::vector<int> v = {1,2,3,4,5}; 
auto i = std::remove(v.begin(),v.end(),3); 
for(auto j = v.begin(); j!= v.end();++j) 
    std::cout << *j; 

salida real: 12455no quite de funcionar correctamente

dónde viene extra de 5 viene?

salida deseada: 1245

cómo lograr lo mismo?

que realmente quieren que el tamaño del vector al cambio, la respuesta dada por Prasoon saurav parece correcto

Respuesta

25

remove doesnt actually remove the elements

Quitar quita de la gama [first, last) todos los elementos que son iguales a value. Es decir, remove devuelve un iterador new_last de modo que el rango [first, new_last) no contiene elementos equivalentes a value. 1 Los iteradores en el rango [new_last, last) son todos aún sin referencias, pero los elementos que señalan son no especificado. Retire es estable, lo que significa que el orden relativo de los elementos que no son iguales a valor es unchanged.` algoritmo

std::remove funciona sólo con un par de iteradores de avance y, en general, no sabe nada acerca del contenedor subyacente.

Es necesario utilizar el lenguaje erase-remove a realidad quitar el elemento es decir combinar con eraseremove

auto i = std::remove(v.begin(),v.end(),3); 
v.erase(i,v.end()); 
for(auto j = v.begin(); j!= v.end();++j) 
    std::cout << *j; 
+4

@Rookie: Mira a ese 'remove()' llamar de nuevo. Ese algoritmo ve una secuencia y no tiene acceso al contenedor, entonces, ¿cómo podría eliminar algo de él? – sbi

+2

"el idioma borrar-eliminar" - que se encuentra al final de la página, en las "notas". –

+2

@GMan: quise votar su respuesta y eliminar mi comentario anterior. ¿Por qué eliminaste tu respuesta? Contiene un punto importante que Prasoon no había hecho (todavía). – sbi

2

remove devuelve la nueva finales. Por lo que la solución de su código es la siguiente:

std::vector<int> v = {1,2,3,4,5}; 
auto newEnd = std::remove(v.begin(),v.end(),3);//return value stored in newEnd 
for(auto j = v.begin(); j!= newEnd ;++j) //note j!=newEnd 
    std::cout << *j; 

Salida:

1245 

hacerlo por su cuenta: http://www.ideone.com/3AMD9

5

leer la documentación de std::remove nuevo.

La función no elimina los elementos de un contenedor (ni siquiera de hecho, se hace saber que un contenedor está involucrado, ya que sólo se ve iteradores), simplemente mueve los valores en una secuencia y devuelve un iterador nuevo i tal que todo el intervalo [ begin .. i [ contiene todos los elementos no eliminados en el orden original. Elementos sobrantes en [ i .. end [ no están especificados, y es su responsabilidad de eliminar ese intervalo de un recipiente (si es preciso):

auto i = std::remove(...); 
v.erase(i,v.end()); 

La razón por la que tiene un adicional de 5 es que el algoritmo de eliminación típica copias valores en los orificios que dejan los valores eliminados, y dado que los valores que superan el iterador i nunca se sobrescriben, siguen siendo los mismos que en la secuencia original.Sin embargo, este comportamiento no es confiable; simplemente elimine los valores pasados ​​i sin leerlos.

-3

Las costuras indican que está imprimiendo la posición n + 1 del vector en la declaración for(). Debería ser:

for(auto j = v.begin(); j!= v.end();j++) 
    std::cout << *j; 

j++ sin ++j

+2

En el contexto de un bucle 'for', 'j ++' y '++ j' son equivalentes (aunque, para los iteradores, puede haber diferencias de rendimiento). –

+0

en este contexto,' j ++ 'y' ++ j' dan como resultado el mismo comportamiento. – xtofl

Cuestiones relacionadas