05 septiembre 2011

Vectores, iteradores y STL…

C  Hace unos días escribí acerca del uso del contenedor vector para poder manejar una lista en C++.  Aunque el vector es muy útil, resulta más interesante y de mayor utilidad si agregamos el uso de iteradores (iterators).  Los iteradores (no sé si esa sea la traducción correcta, pero es lo que más “le suena”) son importantes porque nos permiten accesar de forma fácil a los elementos del contenedor (en este caso un vector), algo así como los apuntadores, solo que más sencillos de manejar y menos susceptibles a errores por parte del programador.  También es importante saber usarlos porque son necesarios para poder usar una serie de algoritmos que ya están programados en la STL y que toman iteradores como parámetros.
Pero, como dijo Jack el destripador: “vámonos por partes”.  Primero voy a decir cómo declarar un iterador, luego como recorrer el vector usándolo, luego funciones que pueden ser de utilidad.

Declarando un iterador

No hay que incluir ninguna librería nueva porque el vector ya lo contiene.  Para declarar uno, la sintaxis sería la siguiente:
vector<tipo>::iterator nombre;
por ejemplo
vector<string>::iterator miIterador;
declara un iterador a un vector de elementos que son de tipo string llamado miIterador.  También es posible declarar iteradores constantes, es decir, que no pueden cambiar de valor.  Esto se haría así:
vector<string>::const_iterator it;
Este ejemplo declara un iterador constante llamado it.

Recorriendo el vector

Si recuerdas en el programa anterior (y si no recuerdas, lee el post anterior que es vital para entender este rollo) podía recorrer el vector manejándolo como si fuera un arreglo.  El código que cumplía tal fin era este (suponiendo que inventario es un vector):
for (unsigned int i = 0; i < inventario.size(); ++i) {
    cout << inventario[i] << endl;
}

Esto está bien, pero con un iterador, puedo hacerlo de la siguiente manera (suponiendo que it es un iterador):
for (it = inventario.begin(); it != inventario.end(); ++it) {
    cout << *it << endl;
}

Fíjate en el operador * que funciona igual que con los apuntadores.

Modificando elementos del vector

También es posible cambiar un elemento del vector.  Supongamos que quiero cambiar lo que tengo de inventario en el primer elemento.  Esto lo podría hacer posicionando el iterador en el primer elemento y usar la notación * para cambiar el valor.  Claro que si quieres cambiar otro elemento, lo tienes que encontrar primero.
it = inventario.begin();
*it = “Guadaña”;

Funciones y elementos del vector

Es posible hacerlo con la misma notación que los apuntadores.  Es decir, si quiero saber el número de elementos del vector inventario puedo hacerlo de cualquiera de estas maneras: (*it).size() o it->size()

Insertando elementos en cualquier posición

Para esto me sirve la función insert.  Supongamos que quiero poner antes del primer elemento un objeto que acabo de encontrar.  Entonces haría lo siguiente:
inventario.insert(inventario.begin(), "Botella llena de Curare");
Claro que si lo quieres insertar en otro lugar, solo posiciona un iterador en el lugar en donde quieres insertarlo y escribe eso en lugar del inventario.begin().

Eliminando cualquier elemento

El contenedor vector tiene la función pop_back para eliminar el último elemento, pero nada más.  ¿Y si quiero eliminar lo que tengo en la posición 3 de mi inventario?  Con iteradores puedo hacerlo de la siguiente manera:
inventario.erase((inventario.begin() + 2));

Y para terminar, referencias y atracciones futuras

Con esto más o menos cubrí lo que puedes hacer con un iterador con el contenedor vector.  Faltaría ver como usar algoritmos de la STL para hacernos la vida todavía más sencilla porque puedo aprovechar funciones ya creadas para ordenar, mezclar, etc.
Para crear este artículo, me basé en el mismo libro de la vez anterior (vuelvo a poner la referencia abajo) y la imagen del C++ chuvidubis es cortesía del blog de Etienne GT.  ¡Hasta la próxima!
Publicar un comentario
Related Posts Plugin for WordPress, Blogger...