1 aula 3 listas e iteradores (cont.). 2003/2004 programação orientada para objectos 2 listadeint :...
TRANSCRIPT
1
Aula 3
Listas e iteradores (cont.)
2003/2004 Programação Orientada para
Objectos2
ListaDeInt: interface
class ListaDeInt { public: typedef int Item;
class Iterador;
ListaDeInt();
Item const& frente() const; Item const& trás() const;
int comprimento() const;
bool estáVazia() const; bool estáCheia() const;
void põeNaFrente(Item const& item);void põeAtrás(Item const& item);void tiraDaFrente();void tiraDeTrás();
void insereAntes(Iterador& iterador, Item const& item);void remove(Iterador& iterador);
void esvazia();
Iterador primeiro();Iterador último();Iterador início();Iterador fim();
2003/2004 Programação Orientada para
Objectos3
ListaDeInt: implementação
class ListaDeInt { …
private: static int const número_máximo_de_itens = 100;
Item itens[número_máximo_de_itens]; int número_de_itens;
bool cumpreInvariante() const;
friend class Iterador;};
return 0 <= número_de_itens and número_de_itens <= número_máximo_de_itens;
2003/2004 Programação Orientada para
Objectos4
ListaDeInt::Iterador:interface
class ListaDeInt::Iterador { public: explicit Iterador(ListaDeInt& lista_associada);
Item& item() const;
bool operator==(Iterador const& outro_iterador) const; bool operator!=(Iterador const& outro_iterador) const;
Iterador& operator++(); Iterador& operator--(); Iterador operator++(int); Iterador operator--(int);
2003/2004 Programação Orientada para
Objectos5
ListaDeInt::Iterador: implementação
class ListaDeInt::Iterador {
…
private: ListaDeInt& lista_associada; int índice_do_item_referenciado;
bool cumpreInvariante() const;
friend class ListaDeInt;};
return -1 <= índice_do_item_referenciado;
2003/2004 Programação Orientada para
Objectos6
Aluno
class Aluno { public: Aluno(string const& nome = “”, int número = 0);
string const& nome() const; int número() const;
private: string nome_; int número_;};
Aluno::Aluno(string const& nome, int const número) : nome_(nome), número_(número) {}
string const& Aluno::nome() const{ return nome_;}
int Aluno::número() const{ return número_;}
2003/2004 Programação Orientada para
Objectos7
Listas de outros tipos
Alterar Nome da lista e respectivo construtor Alterar typedef
Exemplo: ListaDeInt para ListaDeAluno typedef int Item; passa atypedef Aluno Item;
2003/2004 Programação Orientada para
Objectos8
Utilização de listas
int main(){ ListaDeAluno lista;
for(int i = 0; i != 100; ++i) { string nome; // uma só palavra! int número; cin >> nome >> número; Aluno aluno(nome, número);
// Inserir por ordem… }
for(ListaAluno::Iterador i = lista.primeiro(); i != lista.fim(); ++i) cout << i.item().nome() << ' ' << i.item().número() << endl; }
2003/2004 Programação Orientada para
Objectos9
Inserir por ordem
int main(){ ListaDeAluno lista;
for(int i = 0; i != 100; ++i) { string nome; // uma só palavra! int número; cin >> nome >> número; Aluno aluno(nome, número);
ListaDeAluno::Iterador i = lista.primeiro(); while(i != lista.fim() and i.item().nome() < nome) ++i; lista.insereAntes(i, aluno); }
for(ListaAluno::Iterador i = lista.primeiro(); i != lista.fim(); ++i) cout << i.item().nome() << ' ' << i.item().número() << endl; }
2003/2004 Programação Orientada para
Objectos10
Diagrama
lista : ListaDeAluno
itens: Item[100]
i: ListaDeAluno.Iterador
índice_do_item_referenciado: int
5
número_de_itens: int
itens[0]:
Ana12345
...
itens[1]: itens[2]: itens[3]: itens[4]: itens[5]: itens[99]:itens[6]:
Berto11111
Carlos22222
Duarte33333
Xico12121
lista_associada: ListaDeAluno&
2003/2004 Programação Orientada para
Objectos11
Cadeia simplesmente ligada
class ListaDeInt { …
private: …
struct Elo { Item item; int seguinte; };
Elo elos[número_máximo_de_itens];
…};
2003/2004 Programação Orientada para
Objectos12
Diagrama:cadeia simplesmente ligada
elos[0]:
seguinte:
13
item: Aluno
Ana11111
elos[13]:
seguinte:
1
item: Aluno
Berto12345
2003/2004 Programação Orientada para
Objectos13
ListaDeInt::insereAntes()
void ListaDeInt::insereAntes(Iterador const& iterador, Item const& item){ assert(cumpreInvariante());
assert(not estáCheia()); assert(iterador != início());
++número_de_itens;
?
assert(cumpreInvariante());}
int const elo_reservado = reservaElo();
elos[elo_reservado].item = item;
elos[elo_reservado].seguinte = iterador.elo_do_item_referenciado;
2003/2004 Programação Orientada para
Objectos14
Cadeia duplamente ligada
class ListaDeInt { …
private: …
struct Elo { Item item; int anterior; int seguinte; };
…
};
2003/2004 Programação Orientada para
Objectos15
Diagrama:cadeia duplamente ligada
elos[10]:
seguinte:
45
item: Aluno
Ana11111
elos[45]:
seguinte:
11
item: Aluno
Berto12345
anterior:
33
anterior:
10
2003/2004 Programação Orientada para
Objectos16
ListaDeInt::insereAntes()
void ListaDeInt::insereAntes(Iterador const& iterador, Item const& item){ assert(cumpreInvariante());
assert(not estáCheia()); assert(iterador != início());
++número_de_itens;
int const elo_reservado = reservaElo(); elos[elo_reservado].item = item; elos[elo_reservado].seguinte = iterador.elo_do_item_referenciado;
?
assert(cumpreInvariante());}
int const anterior = elos[iterador.elo_do_item_referenciado].anterior;elos[anterior].seguinte = elo_reservado;
2003/2004 Programação Orientada para
Objectos17
ListaDeInt::insereAntes():completo (I)
void ListaDeInt::insereAntes(Iterador const& iterador, Item const& item){ assert(cumpreInvariante());
assert(not estáCheia()); assert(iterador != início());
++número_de_itens;
int const elo_reservado = reservaElo();
(continua)
2003/2004 Programação Orientada para
Objectos18
ListaDeInt::insereAntes():completo (II)
(continuação)
elos[elo_reservado].item = item; elos[elo_reservado].anterior = elos[iterador.elo_do_item_referenciado].anterior; elos[elo_reservado].seguinte = iterador.elo_do_item_referenciado;
int const anterior = elos[iterador.elo_do_item_referenciado].anterior; elos[anterior].seguinte = elo_reservado; elos[iterador.elo_do_item_referenciado].anterior = elo_reservado;
assert(cumpreInvariante());}
2003/2004 Programação Orientada para
Objectos19
Cadeia duplamente ligada com guardas
class ListaDeInt { … private: … struct Elo { Item item; int anterior; int seguinte; }; … Elo elos[número_máximo_de_itens + 2];
static int const inicial = número_máximo_de_itens; static int const final = número_máximo_de_itens + 1; …};
2003/2004 Programação Orientada para
Objectos20
ListaDeInt: construtor
ListaDeInt::ListaDeInt() : número_de_itens(0) { elos[inicial].seguinte = final; elos[final].anterior = inicial;
? // falta aqui qualquer coisa...
assert(cumpreInvariante());}
2003/2004 Programação Orientada para
Objectos21
ListaDeInt::remove() (I)
inline void ListaDeInt::remove(Iterador& iterador) { assert(cumpreInvariante());
assert(not estáVazia()); assert(iterador != início() and iterador != fim());
--número_de_itens;
int const elo_a_remover = iterador.elo_do_item_referenciado;
++iterador; // Avançar iterador!
(continua)
2003/2004 Programação Orientada para
Objectos22
ListaDeInt::remove() (II)
(continuação)
elos[elos[elo_a_remover].anterior].seguinte = elos[elo_a_remover].seguinte; elos[elos[elo_a_remover].seguinte].anterior = elos[elo_a_remover].anterior;
libertaElo(elo_a_remover);
assert(cumpreInvariante());}
2003/2004 Programação Orientada para
Objectos23
A fazer…
reservaElo() libertaElo() Saber quais os elos livres Implementar os restantes métodos Implementar classe Lista.Iterador
2003/2004 Programação Orientada para
Objectos24
Diagrama:cadeia duplamente ligada com guardas
elos[0]:
anterior:
7seguinte:
elos[10]:
Ana11111
item: Aluno
100anterior:
101seguinte:
elos[100]:
anterior:
10seguinte:
elos[101]:
10anterior:
seguinte:
1
número_de_itens: int
100
elo_inicial: int
101
elo_final: int
0
primeiro_elo_livre: int
elos[7]:
anterior:
43seguinte:
2003/2004 Programação Orientada para
Objectos25
Interface vs. implementação
Alteração da implementação não implica alteração da interface
Programas que usavam Lista não precisam de ser alterados
2003/2004 Programação Orientada para
Objectos26
Aula 3
Utilização de listas Fazendo inserções ordenadas
Melhorando a implementação das listas e iteradores: Identificando problemas de eficiência Noções de cadeia simplesmente ligada, cadeia duplamente ligada e
cadeia duplamente ligada com guardas Necessidade de distinguir posições livres Implementação parcial do módulo
Reflexão sobre interfaces e implementação: Vantagens de definir uma boa interface