Вы находитесь на странице: 1из 35

Clase de Iteradores en C++

Algoritmos y estructuras de datos II


Algoritmos y estructuras de datos II Clase de Iteradores en C++
Hasta ahora vimos:

Clases

Manejo de memoria dinamica

Templates
Algoritmos y estructuras de datos II Clase de Iteradores en C++
template <typename T>
class ArregloD {
T* arreglo;
int espacio;
int ultimo;
public:
ArregloD ();
ArregloD( int tamanio );
ArregloD(const ArregloD <T>& otroArreglo );
~ArregloD ();
void insertarAtras( const T& elem );
int tamanio () const;
const T& iesimo( int i ) const;
T& iesimo( int i );
};
Algoritmos y estructuras de datos II Clase de Iteradores en C++
Iteradores

Que es un iterador?

Un objeto que permite atravesar un contenedor.

En general mantienen una interfaz com un y ocultan los


detalles de la estructura que iteran.

Como los usamos en C++?

En C++ los contenedores iterables contienen una clase interna


llamada iterator y metodos para obtener una instancia que
itere a partir de alg un punto.

El estilo de C++ es levemente distinto al estilo que usamos en


la materia en los modulos de dise no, en el TP podran utilizar
el que les sea mas comodo.
Algoritmos y estructuras de datos II Clase de Iteradores en C++
Iteradores

Que es un iterador?

Un objeto que permite atravesar un contenedor.

En general mantienen una interfaz com un y ocultan los


detalles de la estructura que iteran.

Como los usamos en C++?

En C++ los contenedores iterables contienen una clase interna


llamada iterator y metodos para obtener una instancia que
itere a partir de alg un punto.

El estilo de C++ es levemente distinto al estilo que usamos en


la materia en los modulos de dise no, en el TP podran utilizar
el que les sea mas comodo.
Algoritmos y estructuras de datos II Clase de Iteradores en C++
Iteradores

Que es un iterador?

Un objeto que permite atravesar un contenedor.

En general mantienen una interfaz com un y ocultan los


detalles de la estructura que iteran.

Como los usamos en C++?

En C++ los contenedores iterables contienen una clase interna


llamada iterator y metodos para obtener una instancia que
itere a partir de alg un punto.

El estilo de C++ es levemente distinto al estilo que usamos en


la materia en los modulos de dise no, en el TP podran utilizar
el que les sea mas comodo.
Algoritmos y estructuras de datos II Clase de Iteradores en C++
Iteradores

Que es un iterador?

Un objeto que permite atravesar un contenedor.

En general mantienen una interfaz com un y ocultan los


detalles de la estructura que iteran.

Como los usamos en C++?

En C++ los contenedores iterables contienen una clase interna


llamada iterator y metodos para obtener una instancia que
itere a partir de alg un punto.

El estilo de C++ es levemente distinto al estilo que usamos en


la materia en los modulos de dise no, en el TP podran utilizar
el que les sea mas comodo.
Algoritmos y estructuras de datos II Clase de Iteradores en C++
Iteradores

Que es un iterador?

Un objeto que permite atravesar un contenedor.

En general mantienen una interfaz com un y ocultan los


detalles de la estructura que iteran.

Como los usamos en C++?

En C++ los contenedores iterables contienen una clase interna


llamada iterator y metodos para obtener una instancia que
itere a partir de alg un punto.

El estilo de C++ es levemente distinto al estilo que usamos en


la materia en los modulos de dise no, en el TP podran utilizar
el que les sea mas comodo.
Algoritmos y estructuras de datos II Clase de Iteradores en C++
Declarando un iterador `a la Algo 2
template <typename T>
class ArregloD {
public:
...
class Iterador {
ArregloD <T>* arreglo;
int indice;
Iterador(ArregloD <T>* arreglo , int indice );
friend Iterador ArregloD <T>:: crearIt ();
public:
bool hayMas () const;
T& actual ();
void avanzar ();
};
Iterador crearIt ();
};
Algoritmos y estructuras de datos II Clase de Iteradores en C++
Deniendo un iterador `a la Algo 2
template <typename T>
typename ArregloD <T>:: Iterador
ArregloD <T>:: crearIt () {
Iterador it(this , 0);
return it;
}
template <typename T>
ArregloD <T>:: Iterador :: Iterador(
ArregloD* a, int i) :
arreglo(a), indice(i) {}
Algoritmos y estructuras de datos II Clase de Iteradores en C++
Deniendo un iterador `a la Algo 2
template <typename T>
bool ArregloD <T>:: Iterador :: hayMas () const {
return indice < arreglo ->tamanio ();
}
template <typename T>
T& ArregloD <T>:: Iterador :: actual () {
return arreglo ->iesimo(indice );
}
template <typename T>
void ArregloD <T>:: Iterador :: avanzar () {
indice ++;
}
Algoritmos y estructuras de datos II Clase de Iteradores en C++
Declarando un iterador `a la Algo 2
template <typename T>
class ArregloD {
public:
...
class Iterador_const {
const ArregloD <T>* arreglo;
int indice;
Iterador_const(const ArregloD <T>* arreglo , int indice );
friend Iterador_const ArregloD <T>:: crearIt () const;
public:
bool hayMas () const;
const T& actual ();
void avanzar ();
};
Iterador_const crearIt () const;
};
Algoritmos y estructuras de datos II Clase de Iteradores en C++
Deniendo un iterador `a la Algo 2
template <typename T>
typename ArregloD <T>:: Iterador_const
ArregloD <T>:: crearIt () const {
Iterador_const it(this , 0);
return it;
}
template <typename T>
ArregloD <T>:: Iterador_const :: Iterador_const(
const ArregloD* a, int i) :
arreglo(a), indice(i) {}
template <typename T>
const T& ArregloD <T>:: Iterador_const :: actual () {
return arreglo ->iesimo(indice );
}
Algoritmos y estructuras de datos II Clase de Iteradores en C++
Ventajas:

Permite manipular ecientemente el contenedor manteniendo


oculta su representacion interna.

Podemos usar iteradores como punteros seguros a la


estructura interna sin exponerla.

Permite escribir algoritmos genericos (asumiendo una interfaz


com un).
Algoritmos y estructuras de datos II Clase de Iteradores en C++
Ventajas:

Permite manipular ecientemente el contenedor manteniendo


oculta su representacion interna.

Podemos usar iteradores como punteros seguros a la


estructura interna sin exponerla.

Permite escribir algoritmos genericos (asumiendo una interfaz


com un).
Algoritmos y estructuras de datos II Clase de Iteradores en C++
Ventajas:

Permite manipular ecientemente el contenedor manteniendo


oculta su representacion interna.

Podemos usar iteradores como punteros seguros a la


estructura interna sin exponerla.

Permite escribir algoritmos genericos (asumiendo una interfaz


com un).
Algoritmos y estructuras de datos II Clase de Iteradores en C++
Ventajas:

Permite manipular ecientemente el contenedor manteniendo


oculta su representacion interna.

Podemos usar iteradores como punteros seguros a la


estructura interna sin exponerla.

Permite escribir algoritmos genericos (asumiendo una interfaz


com un).
Algoritmos y estructuras de datos II Clase de Iteradores en C++
template <typename T>
class Lista {
struct Nodo {
T elem;
Nodo *anterior , *siguiente;
Nodo(const T& e, Nodo* ant , Nodo* sig) :
elem(e), anterior(ant), siguiente(sig) {}
};
Nodo* cabeza;
public:
class Iterador {
Lista <T>* lista;
Nodo* nodo;
Iterador(Lista* lista , Nodo* nodo);
friend class Lista <T>;
public:
Iterador insertar(const T& e);
void remover ();
};
Lista ();
Iterador agregar(const T& t);
};
Algoritmos y estructuras de datos II Clase de Iteradores en C++
template <typename T>
Lista <T>:: Lista() : cabeza(NULL) {}
template <typename T>
typename Lista <T>:: Iterador
Lista <T>:: agregar(const T& e)
{
cabeza = new Nodo(e, NULL , cabeza );
if (cabeza ->siguiente != NULL)
cabeza ->siguiente ->anterior = cabeza;
typename Lista <T>:: Iterador it(this , cabeza );
return it;
}
Algoritmos y estructuras de datos II Clase de Iteradores en C++
template <typename T>
Lista <T>:: Iterador :: Iterador(Lista <T>* l, Nodo* n) :
lista(l), nodo(n) {}
template <typename T>
typename Lista <T>:: Iterador
Lista <T>:: Iterador :: insertar(const T& e)
{
Nodo* nodo = new Nodo(e, nodo , nodo ->siguiente );
if (nodo ->siguiente != NULL)
nodo ->siguiente ->anterior = nodo;
nodo ->siguiente = nodo;
Iterador it(lista , nodo);
return it;
}
Algoritmos y estructuras de datos II Clase de Iteradores en C++
template <typename T>
void Lista <T>:: Iterador :: remover ()
{
if (nodo == lista ->cabeza) {
lista ->cabeza = nodo ->siguiente;
nodo ->siguiente ->anterior = NULL;
} else {
nodo ->anterior ->siguiente = nodo ->siguiente;
if (nodo ->siguiente != NULL)
nodo ->siguiente ->anterior = nodo ->anterior;
}
delete nodo;
}
Algoritmos y estructuras de datos II Clase de Iteradores en C++
Iteradores `a la C++
C++, Java, Python y muchos otros lenguajes hace un uso intensivo
de iteradores, cada uno tiene su propia manera de hacerlos.
En C++:

Los iteradores deben proveer los operadores *, ++, ->, == y


otros dependiendo del tipo del iterador.

Los objetos iterables usualmente tiene una clase interna


iterator (y/o const iterator) de forma similar a como lo
hicimos hasta ahora.

Los objetos iterables usualmente aceptan los metodos


begin() y end() (y potencialmente rbegin() y rend()).
Algoritmos y estructuras de datos II Clase de Iteradores en C++
template <typename T>
class Lista {
Nodo* cabeza;
Nodo* fin;
...
public:
class iterator {
Lista <T>* lista;
Nodo* nodo;
bool valido;
...
public:
T& operator *();
bool operator ==( const Lista <T>:: iterator& otro) const;
bool operator !=( const Lista <T>:: iterator& otro) const;
iterator& operator ++();
iterator operator ++( int);
iterator& operator --();
iterator operator --(int);
};
iterator begin ();
iterator end();
};
Algoritmos y estructuras de datos II Clase de Iteradores en C++
template <typename T>
T& Lista <T>:: iterator :: operator *() {
return nodo ->elem;
}
template <typename T>
typename Lista <T>:: iterator& Lista <T>:: iterator :: operator ++() {
valido = nodo ->siguiente != NULL;
if (valido)
nodo = nodo ->siguiente;
return *this;
}
template <typename T>
typename Lista <T>:: iterator Lista <T>:: iterator ::operator --(int) {
iterator it(*this);
valido = nodo ->anterior != NULL;
if (valido)
nodo = nodo ->anterior;
return it;
}
template <typename T>
bool Lista <T>:: iterator :: operator ==(
const Lista <T>:: iterator& otro) const {
return valido == otro.valido && nodo == otro.nodo;
}
Algoritmos y estructuras de datos II Clase de Iteradores en C++
Algoritmos genericos sobre iteradores en C++
El header algorithm tiene denidas un gran n umero de funciones
con clases templatizadas asumiendo que cumplen con la interfaz de
los iteradores. Por lo que cualquier clase que que siga
correctamente el patron automaticamente tiene todos esos
algoritmos a su disposicion sin necesidad de implementarlos.
Ejemplos:

nd

count

replace

reverse

sort

random shue

min

max
Algoritmos y estructuras de datos II Clase de Iteradores en C++
Algoritmo de b usqueda de algorithm.h
template <class InputIterator , class T>
InputIterator find (
InputIterator first ,
InputIterator last ,
const T& value )
{
for (; first != last && *first != value; ++ first);
return first;
}
Algoritmos y estructuras de datos II Clase de Iteradores en C++
Tipos de iteradores
Los iteradores en C++ se separan en distintas categoras, lo que
permite implementar algoritmos genericos de distinta forma para
cada tipo de iterador:
1. Input
2. Output
3. Forward
4. Bidirectional
5. Random access
Para denir a que categora pertenece un iterador se utilizan
miembros de la clase iterator traits. Esto puede hacerse de
distintas formas, pero usualmente incluye herencia o
especializacion de templates por lo que queda fuera de este curso.
Algoritmos y estructuras de datos II Clase de Iteradores en C++
Recomendaciones al pasar del dise no a la implementacion

Por cada modulo hacer una clase y un test.

Hacer una clase interna por cada iterador en el modulo (y una


analoga const si tiene sentido).

Recordar que las clases templatizadas no forman unidades de


compilacion (ojo con los cpp que no deben compilarse).

Tener siempre presente el scope de las variables y los objetos.

Identicar que cosas deben alocarse en memoria dinamica y


que cosas no.

Hacer delete de todo lo que se hace new, pero de nada mas.

LO MAS IMPORTANTE DE TODO ES PROGRAMAR DE


FORMA INCREMENTAL. ESCRIBIR UNA FUNCI

ON, SU
TEST, COMPILAR Y PROBAR ANTES DE SEGUIR.
Algoritmos y estructuras de datos II Clase de Iteradores en C++
Recomendaciones al pasar del dise no a la implementacion

Por cada modulo hacer una clase y un test.

Hacer una clase interna por cada iterador en el modulo (y una


analoga const si tiene sentido).

Recordar que las clases templatizadas no forman unidades de


compilacion (ojo con los cpp que no deben compilarse).

Tener siempre presente el scope de las variables y los objetos.

Identicar que cosas deben alocarse en memoria dinamica y


que cosas no.

Hacer delete de todo lo que se hace new, pero de nada mas.

LO MAS IMPORTANTE DE TODO ES PROGRAMAR DE


FORMA INCREMENTAL. ESCRIBIR UNA FUNCI

ON, SU
TEST, COMPILAR Y PROBAR ANTES DE SEGUIR.
Algoritmos y estructuras de datos II Clase de Iteradores en C++
Recomendaciones al pasar del dise no a la implementacion

Por cada modulo hacer una clase y un test.

Hacer una clase interna por cada iterador en el modulo (y una


analoga const si tiene sentido).

Recordar que las clases templatizadas no forman unidades de


compilacion (ojo con los cpp que no deben compilarse).

Tener siempre presente el scope de las variables y los objetos.

Identicar que cosas deben alocarse en memoria dinamica y


que cosas no.

Hacer delete de todo lo que se hace new, pero de nada mas.

LO MAS IMPORTANTE DE TODO ES PROGRAMAR DE


FORMA INCREMENTAL. ESCRIBIR UNA FUNCI

ON, SU
TEST, COMPILAR Y PROBAR ANTES DE SEGUIR.
Algoritmos y estructuras de datos II Clase de Iteradores en C++
Recomendaciones al pasar del dise no a la implementacion

Por cada modulo hacer una clase y un test.

Hacer una clase interna por cada iterador en el modulo (y una


analoga const si tiene sentido).

Recordar que las clases templatizadas no forman unidades de


compilacion (ojo con los cpp que no deben compilarse).

Tener siempre presente el scope de las variables y los objetos.

Identicar que cosas deben alocarse en memoria dinamica y


que cosas no.

Hacer delete de todo lo que se hace new, pero de nada mas.

LO MAS IMPORTANTE DE TODO ES PROGRAMAR DE


FORMA INCREMENTAL. ESCRIBIR UNA FUNCI

ON, SU
TEST, COMPILAR Y PROBAR ANTES DE SEGUIR.
Algoritmos y estructuras de datos II Clase de Iteradores en C++
Recomendaciones al pasar del dise no a la implementacion

Por cada modulo hacer una clase y un test.

Hacer una clase interna por cada iterador en el modulo (y una


analoga const si tiene sentido).

Recordar que las clases templatizadas no forman unidades de


compilacion (ojo con los cpp que no deben compilarse).

Tener siempre presente el scope de las variables y los objetos.

Identicar que cosas deben alocarse en memoria dinamica y


que cosas no.

Hacer delete de todo lo que se hace new, pero de nada mas.

LO MAS IMPORTANTE DE TODO ES PROGRAMAR DE


FORMA INCREMENTAL. ESCRIBIR UNA FUNCI

ON, SU
TEST, COMPILAR Y PROBAR ANTES DE SEGUIR.
Algoritmos y estructuras de datos II Clase de Iteradores en C++
Recomendaciones al pasar del dise no a la implementacion

Por cada modulo hacer una clase y un test.

Hacer una clase interna por cada iterador en el modulo (y una


analoga const si tiene sentido).

Recordar que las clases templatizadas no forman unidades de


compilacion (ojo con los cpp que no deben compilarse).

Tener siempre presente el scope de las variables y los objetos.

Identicar que cosas deben alocarse en memoria dinamica y


que cosas no.

Hacer delete de todo lo que se hace new, pero de nada mas.

LO MAS IMPORTANTE DE TODO ES PROGRAMAR DE


FORMA INCREMENTAL. ESCRIBIR UNA FUNCI

ON, SU
TEST, COMPILAR Y PROBAR ANTES DE SEGUIR.
Algoritmos y estructuras de datos II Clase de Iteradores en C++
Recomendaciones al pasar del dise no a la implementacion

Por cada modulo hacer una clase y un test.

Hacer una clase interna por cada iterador en el modulo (y una


analoga const si tiene sentido).

Recordar que las clases templatizadas no forman unidades de


compilacion (ojo con los cpp que no deben compilarse).

Tener siempre presente el scope de las variables y los objetos.

Identicar que cosas deben alocarse en memoria dinamica y


que cosas no.

Hacer delete de todo lo que se hace new, pero de nada mas.

LO MAS IMPORTANTE DE TODO ES PROGRAMAR DE


FORMA INCREMENTAL. ESCRIBIR UNA FUNCI

ON, SU
TEST, COMPILAR Y PROBAR ANTES DE SEGUIR.
Algoritmos y estructuras de datos II Clase de Iteradores en C++
Ejercicio
Implemente una clase Rosetree (un arbol con una cantidad
arbitraria de hijos) con un iterador preorder `a la C++.
Permita agregar y eliminar elementos a traves del iterador
retornando un iterador nuevo cuando corresponda.
Puede hacer uso de las listas enlazadas y los algoritmos sobre
iteradores de la librera standard:
#include <list >
#include <algorithm >
En la pagina http://www.cplusplus.com/reference/ pueden
encontrar la documentacion de estos modulos.
Algoritmos y estructuras de datos II Clase de Iteradores en C++