A continuación se muestra un fragmento de mi programa. Repito un vector e intento eliminar todo el elemento que tiene el valor de tres. Pero después de imprimir el contenido del vector, es 1-2-4-3-5, todavía tiene un número 3. ¿Por qué? ¿Tenemos que lidiar con el iterador especialmente si queremos eliminar dos elementos iguales consecutivos?

int main()
{
    std::vector<int> a = {1, 2, 3, 4, 3, 3, 5}; // a has size 5
    for(auto it=a.begin();it!=a.end();)
    {
        if(*it == 3) it=a.erase(it);
        it++;
    }
    for(auto x:a) cout<<x<<endl;
}
-1
Caiyi Zhou 12 mar. 2021 a las 11:46

3 respuestas

La mejor respuesta

Podemos desglosar su ejemplo y solo mirar los últimos tres números 3, 3, 5.

Después de borrar los primeros 3, un iterador dos, el segundo 3 se devuelve en

it = a.erase(it);

Pero inmediatamente después de este it se incrementa en

it++;

Y ahora apunta al 5.


Aquí puede utilizar el erase-remove-idiom. Código de ejemplo:

a.erase(std::remove(a.begin(), a.end(), 3), a.end());
4
churill 12 mar. 2021 a las 09:00

Hay un método en <algorithm> llamado remove_if(first, last, func) que resolverá su propósito. Es mas seguro. Compruebe el siguiente código recortado:

#include <iostream>
#include <vector>
#include <algorithm>
bool isThree(int k){
   return (k == 3);
}

int main(){

  std::vector<int> v {1,2,3,4,5,6,7,3,3,3};
  std::vector<int>::iterator it;
  
  v.erase(std::remove_if(v.begin(), v.end(), isThree), v.end());

  for(int i=0;i<v.size(); i++){
     std::cout << v[i] << " ";
  }

  return 0;
}
2
Blastfurnace 12 mar. 2021 a las 15:09

El error es que omite la verificación de un elemento cada vez que elimina uno. Esto se debe a que it = a.erase(it); mueve todos los elementos hacia atrás más allá de it y devuelve it; para solucionar el problema, simplemente no incremente it cuando borre:

for(auto it=a.begin();it!=a.end();)
{
    if(*x == 3) it=a.erase(it); else it++;
}

Además, este código es lento porque potencialmente son operaciones de o(n^2); será mejor que uses std::remove y luego active el borrado / cambio de tamaño para que el vector tenga el tamaño correcto.

1
ALX23z 12 mar. 2021 a las 09:02