2008 lcg/ufrj. all rights reserved. 1 standard template library stl claudio esperança paulo roma...

27
1 2008 LCG/UFRJ. All rights reserved. Standard Template Library Standard Template Library STL STL Claudio Esperança Paulo Roma Cavalcanti

Upload: internet

Post on 17-Apr-2015

109 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: 2008 LCG/UFRJ. All rights reserved. 1 Standard Template Library STL Claudio Esperança Paulo Roma Cavalcanti

1 2008 LCG/UFRJ. All rights reserved.

Standard Template LibraryStandard Template Library STL STL

Claudio EsperançaPaulo Roma Cavalcanti

Page 2: 2008 LCG/UFRJ. All rights reserved. 1 Standard Template Library STL Claudio Esperança Paulo Roma Cavalcanti

2 2008 LCG/UFRJ. All rights reserved.

O que é a STL?O que é a STL?

• STL é uma biblioteca padrão com as estruturas de dados mais usadas em Computação. ▪Foi criada para evitar a implementação e

teste das mesmas estruturas de dados eternamente.

▪Por isso, economiza muito tempo e evita “dor de cabeça” desnecessária.

• Por que templates?▪Elas lhe poupam da tarefa de

reimplementar o código para cada novo tipo de dado da sua aplicação.

Page 3: 2008 LCG/UFRJ. All rights reserved. 1 Standard Template Library STL Claudio Esperança Paulo Roma Cavalcanti

3 2008 LCG/UFRJ. All rights reserved.

STLSTL

• Quando usadas apropriadamente, as templates são bastante eficazes.▪ No entanto, as mensagens de erro costumam

ser pouco elucidativas.• Uma boa fonte sobre a STL é o guia de

programação da SGI.▪ Ou então a nossa implementação de um

subconjunto da STL.• Na nossa implementação, cada classe tem o

prefixo “utl” (não havia namespace ainda).▪ Se a variável de compilação USE_STL estiver

definida, o prefixo será suprimido, “cgcUtil::” será substituído por “std::”, e o compilador usará a STL nativa então.

Page 4: 2008 LCG/UFRJ. All rights reserved. 1 Standard Template Library STL Claudio Esperança Paulo Roma Cavalcanti

4 2008 LCG/UFRJ. All rights reserved.

Estrutura da STLEstrutura da STL

• A STL oferece:▪Containers (recipientes).▪ Iterators (iteradores).▪Algorithms (algoritmos).

• Recipientes servem para armazenar dados e podem ser classificados como:▪Seqüências de dados ▪Recipientes associativos para pares de

objetos (chave, dado).▪Adaptadores que provêem um

subconjunto da funcionalidade de um recipiente.◦Pilhas, filas, filas de prioridade.

Page 5: 2008 LCG/UFRJ. All rights reserved. 1 Standard Template Library STL Claudio Esperança Paulo Roma Cavalcanti

5 2008 LCG/UFRJ. All rights reserved.

IteradoresIteradores

• Iteradores foram criados para permitir uma maneira unificada de percorrer ou recuperar dados de recipientes.▪Escondem os detalhes de implementação,

principalmente ponteiros, das aplicações.▪Portanto, geralmente é possível trocar o

tipo de recipiente e ainda assim usar o mesmo código.

• A STL adota a filosofia de manter os algoritmos fora das classes dos recipientes.▪A razão é permitir que o mesmo algoritmo

possa agir sobre recipientes diferentes.

Page 6: 2008 LCG/UFRJ. All rights reserved. 1 Standard Template Library STL Claudio Esperança Paulo Roma Cavalcanti

6 2008 LCG/UFRJ. All rights reserved.

ExemploExemplo

• Geralmente os algoritmos são implementados usando iteradores apenas.▪Ordenação, busca, contagem,

substituição, etc...▪Iteradores tem operadores de

incremento “++” definidos. ▪Ponteiros podem ser usados como

iteradores.

Page 7: 2008 LCG/UFRJ. All rights reserved. 1 Standard Template Library STL Claudio Esperança Paulo Roma Cavalcanti

7

2008 LCG/UFRJ. All rights reserved.

Imprimindo Imprimindo elementos de elementos de

um vetorum vetor

#include <vector>#include <iostream>using namespace std; /** função objeto. * Insere T em um stream de saída. * Substitui “passar ponteiro para função” de C. */template <class T> struct print : public unary_function <T, void> {

print(ostream& out) : os(out), count(0) {} void operator() (T x) { os << x << ' '; ++count; } ostream& os; int count; }; int main() { int A[] = {1, 4, 2, 8, 5, 7}; const int N = sizeof(A) / sizeof(int);

print<int> P = for_each(A, A + N, print<int>(cout)); cout << endl << P.count << " objects printed." << endl;

return 1; }

1 4 2 8 5 76 objects printed.

Calcula o tamanho

de A Dois iteradore

s

Redefine operador

( )

Construtor

Guarda número

de elemento

s impresso

s

Chama print() para

cada elemento de

A

Page 8: 2008 LCG/UFRJ. All rights reserved. 1 Standard Template Library STL Claudio Esperança Paulo Roma Cavalcanti

8 2008 LCG/UFRJ. All rights reserved.

VectorVector

• vector é o recipiente mais simples da STL.▪É uma seqüência que suporta acesso

aleatório aos seus elementos.▪ Inserção e remoção de elementos no final

em O(1).▪ Inserção e remoção de elementos no meio

em O(n).▪Busca em O(n).▪Gerenciamento automático de memória.▪ Iteradores estão invalidados após

realocação de memória, inserção e remoção no meio.

▪Descrição e implementação.

Page 9: 2008 LCG/UFRJ. All rights reserved. 1 Standard Template Library STL Claudio Esperança Paulo Roma Cavalcanti

9

2008 LCG/UFRJ. All rights reserved.

Uso da classe Uso da classe vectorvector..

#include <vector>#include <iostream>#include <iterator>#include <ext/algorithm>using namespace std;using __gnu_cxx::is_sorted;

int main(){ vector<int> V; V.push_back(20); V.push_back(30); V.push_back(-1); V.push_back(-1); V.push_back(-1); cout << "V: \n"; copy(V.begin(), V.end(), ostream_iterator<int>(cout, " ")); stable_sort (V.begin(), V.end()); cout << "\nV: sorted\n"; copy(V.begin(), V.end(), ostream_iterator<int>(cout, " ")); cout << "\nV: is sorted? "; cout << is_sorted ( V.begin(), V.end() ) << "\n";}

V: 20 30 -1 -1 -1 V: sorted-1 -1 -1 20 30 V: is sorted? 1

Insere no final de

V.Insere V

no stream

de saída

Ordena V com

merge sort. Verifica

se V está ordenado

.

Page 10: 2008 LCG/UFRJ. All rights reserved. 1 Standard Template Library STL Claudio Esperança Paulo Roma Cavalcanti

10

2008 LCG/UFRJ. All rights reserved.

FunçãoFunção copy copy..

/** copies elements from a container to another. * * Copies elements from the range [first, last) to the * range [result, result + (last - first)). * That is, it performs the assignments * *result = *first, *(result + 1) = *(first + 1), and so on. * Generally, for every integer n from 0 to last - first, * copy() performs the assignment *(result + n) = *(first + n). * Assignments are performed in forward order, i.e. in order of * increasing n. * * The return value is result + (last - first) * * @param first where to start copying. * @param last where to end copying. * @param result where to copy. * @return result + (last-first). */template<class InputIterator, class OutputIterator> inline OutputIterator copy(InputIterator first, InputIterator last, OutputIterator result) { for( InputIterator itr = first; itr != last; ++itr, ++result ) {

*result = *itr; } return result;}

Apenas percorre o

recipiente de entrada.

E atribui ao

recipiente da

saída.

Derivados da mesma

classe base.

Page 11: 2008 LCG/UFRJ. All rights reserved. 1 Standard Template Library STL Claudio Esperança Paulo Roma Cavalcanti

11 2008 LCG/UFRJ. All rights reserved.

DequeDeque

• deque (Double Ended Queue) é como um vetor com inserção eficiente na frente também.▪ É uma seqüência que suporta acesso aleatório

aos seus elementos.▪ Inserção e remoção de elementos no meio em

O(n).▪ Busca em O(n).▪ Inserção e remoção de elementos na frente e no

final em O(1).▪ Gerenciamento automático de memória.▪ Iteradores estão invalidados após realocação de

memória, inserção e remoção no meio.▪ Descrição e implementação.

Page 12: 2008 LCG/UFRJ. All rights reserved. 1 Standard Template Library STL Claudio Esperança Paulo Roma Cavalcanti

12

2008 LCG/UFRJ. All rights reserved.

Uso da classe Uso da classe ddequeeque..

#include <deque>#include <iostream>#include <iterator>

using namespace std;

int main() {

deque<int> Q;Q.push_back(3);Q.push_front(1);Q.insert(Q.begin() + 1, 2);Q[2] = 0;copy(Q.begin(), Q.end(), ostream_iterator<int>(cout, " "));cout << "\n";// The values that are printed are 1 2 0Q.insert(Q.begin() + 1, (size_t)3, 5);Q.push_front(7);Q.push_front(8);Q.push_front(9);

Insere 5 três vezes

após a primeira posição.

Page 13: 2008 LCG/UFRJ. All rights reserved. 1 Standard Template Library STL Claudio Esperança Paulo Roma Cavalcanti

13

2008 LCG/UFRJ. All rights reserved.

Uso da classe Uso da classe dequedeque..

copy(Q.begin(), Q.end(), ostream_iterator<int>(cout, " "));cout << "\n";deque<int> P = Q;copy(Q.begin(), Q.end(), ostream_iterator<int>(cout, " "));cout << "\n";P.resize ( 18, 88 );P.push_front ( 99 );P.push_front ( 98 );copy(P.begin(), P.end(), ostream_iterator<int>(cout, " "));P.erase ( P.begin(), P.begin()+2 );cout << "\n";cout << P.back();cout << "\n";cout << P.front();cout << "\n";cout << *P.begin();cout << "\n";}

1 2 09 8 7 1 5 5 5 2 09 8 7 1 5 5 5 2 098 99 9 8 7 1 5 5 5 2 0 88 88 88 88 88 88 88 88 88889

9

Redimensiona P

completando com 88 no

final.Remove os

dois primeiros elementos

de P.Último

elemento de P

Primeiro elemento

de P

Page 14: 2008 LCG/UFRJ. All rights reserved. 1 Standard Template Library STL Claudio Esperança Paulo Roma Cavalcanti

14 2008 LCG/UFRJ. All rights reserved.

ListList

• list é de fato uma lista duplamente encadeada. ▪É uma seqüência que suporta percurso

para frente e para trás. ▪Busca em O(n).▪Inserção e remoção de elementos na

frente, no meio e no final em O(1).▪Iteradores ainda estão válidos após

inserção, splicing ou remoção.▪Descrição, Implementação.

Page 15: 2008 LCG/UFRJ. All rights reserved. 1 Standard Template Library STL Claudio Esperança Paulo Roma Cavalcanti

15

2008 LCG/UFRJ. All rights reserved.

Uso da classe Uso da classe listlist..

#include <list>#include <iostream>#include <iterator>

using namespace std;

int main(){ list<int> L; L.push_back(0); L.push_front(1); L.insert(++L.begin(), 2); copy(L.begin(), L.end(), ostream_iterator<int>(cout, " ")); cout << "\n"; list<int> M ( L ); L.splice ( ++++L.begin(), M ); copy(L.begin(), L.end(), ostream_iterator<int>(cout, " ")); cout << “\n”; copy(M.begin(), M.end(), ostream_iterator<int>(cout, " "));}

1 2 01 2 1 2 0 0

Insere 0 no final

de LInsere 1 no início

de L.

Insere 2 após a

primeira posição.Move

elementos de M para

L.

M está vazia.

Page 16: 2008 LCG/UFRJ. All rights reserved. 1 Standard Template Library STL Claudio Esperança Paulo Roma Cavalcanti

16 2008 LCG/UFRJ. All rights reserved.

StringString

• string toma o lugar de um “array of char”.▪Não é mais necessário se preocupar

com o tamanho do arranjo. ▪Oferece todas as funções de C

pertinentes a strings como membros da classe.

▪Evita erros relacionados com ponteiros, na chamada de funções que recebem ou retornam strings.

▪Descrição, Implementação.

Page 17: 2008 LCG/UFRJ. All rights reserved. 1 Standard Template Library STL Claudio Esperança Paulo Roma Cavalcanti

17

2008 LCG/UFRJ. All rights reserved.

Uso da classe Uso da classe stringstring..

#include <string>#include <iostream>using namespace std;

int main () { //test constructors string str0; cout << "empty constructor: " << str0 << endl; cout << "str0 size = " << str0.size() << endl; string str1("hellow world!"); // 0123456789012 cout << "const char constructor: " << str1 << endl; cout << "data = " << str1.data() << endl; cout << "size = " << str1.size() << endl; cout << "length = " << str1.length() << endl; cout << "capacity = " << str1.capacity() << endl; cout << "max_size = " << str1.max_size() << endl; // empty cout << "str0 empty = " << str0.empty() << endl; cout << "str1 empty = " << str1.empty() << endl;

empty constructor: str0 size = 0const char constructor: hellow world!data = hellow world!size = 13length = 13capacity = 13max_size = 13str0 empty = 1str1 empty = 0

Capacidade da string

sem ter de realocar.

Tamanho máximo que uma string pode ter.

Comprimento atual da

string

O mesmo que length.

Page 18: 2008 LCG/UFRJ. All rights reserved. 1 Standard Template Library STL Claudio Esperança Paulo Roma Cavalcanti

18

2008 LCG/UFRJ. All rights reserved.

Uso da classe Uso da classe stringstring..

string str2(str1); cout << “copy constructor: " << str2 << endl; string str3(str1, 4, 6); cout << "string&, pos, npos, str3 constructor: " << str3 << endl; string str4("hellow word!", 6); cout << "char[], npos, str4 constructor: " << str4 << endl; string str5(12, 'h'); cout << “n, char str5 constructor: " << str5 << endl; cout << "str5 size = " << str5.size() << endl; // swap str5.swap(str1); cout << "swap str1 and str5" << endl; cout << "str1 = " << str1 << endl; cout << "str5 = " << str5 << endl;}

copy constructor: hellow world!string&, pos, npos, str3 constructor: ow worchar[], npos, str4 constructor: hellown, char str5 constructor: hhhhhhhhhhhhstr5 size = 12swap str1 and str5str1 = hhhhhhhhhhhhstr5 = hellow world!

Troca o conteúdo

de str5 por str1.

Page 19: 2008 LCG/UFRJ. All rights reserved. 1 Standard Template Library STL Claudio Esperança Paulo Roma Cavalcanti

19 2008 LCG/UFRJ. All rights reserved.

SetSet

• set é uma coleção ordenada de objetos do tipo “key” sem duplicatas.▪Operações de conjunto como interseção,

união e diferença são eficientes.▪ Implementado por uma árvore

balanceada de busca (Red Black, Splay).▪Busca em O(log n).▪Descrição, Implementação.

• multiset é a versão que permite duplicatas.▪Descrição, Implementação.

Page 20: 2008 LCG/UFRJ. All rights reserved. 1 Standard Template Library STL Claudio Esperança Paulo Roma Cavalcanti

20

2008 LCG/UFRJ. All rights reserved.

Uso da classe Uso da classe setset..

#include <set>#include <iostream>using namespace std;

/// função objeto. Compara duas seqüências de caracteres.struct ltstr{ bool operator()(const char* s1, const char* s2) const { return strcmp(s1, s2) < 0; }};

int main(){ const int N = 6; const char* a[N] = {"isomer", "ephemeral", "prosaic", "nugatory", "artichoke", "serif"}; const char* b[N] = {"flat", "this", "artichoke", "frigate", "prosaic", "isomer"};

set<const char*,ltstr> A(a, a + N); set<const char*,ltstr> B(b, b + N); set<const char*,ltstr> C;

Retorna se s1 é lexicograficam

ente menor que s2

Construtor a partir de dois

iteradores

Page 21: 2008 LCG/UFRJ. All rights reserved. 1 Standard Template Library STL Claudio Esperança Paulo Roma Cavalcanti

21

2008 LCG/UFRJ. All rights reserved.

Uso da classe Uso da classe setset..

cout << "Set A: "; copy(A.begin(), A.end(), ostream_iterator <const char*>(cout, " ")); cout << endl; cout << "Set B: "; copy(B.begin(), B.end(), ostream_iterator <const char*>(cout, " ")); cout << endl;

cout << "Union: "; set_union(A.begin(), A.end(), B.begin(), B.end(), ostream_iterator<const char*>(cout, " "), ltstr()); cout << endl;

cout << "Intersection: "; set_intersection(A.begin(), A.end(), B.begin(), B.end(), ostream_iterator<const char*>(cout, " "), ltstr()); cout << endl;

set_difference(A.begin(), A.end(), B.begin(), B.end(), inserter(C, C.begin()), ltstr()); cout << "Set C (difference of A and B): "; copy(C.begin(), C.end(), ostream_iterator <const char*>(cout, " ")); cout << endl;}

Set A: artichoke ephemeral isomer nugatory prosaic serif Set B: artichoke flat frigate isomer prosaic this Union: artichoke ephemeral flat frigate isomer nugatory prosaic serif this Intersection: artichoke isomer prosaic

Set C (difference of A and B): ephemeral nugatory serif

A ∪ B.

A ∩ B.

A – B.

Insere o resultado

em C.

Page 22: 2008 LCG/UFRJ. All rights reserved. 1 Standard Template Library STL Claudio Esperança Paulo Roma Cavalcanti

22 2008 LCG/UFRJ. All rights reserved.

MapMap

• map associa objetos do tipo “key” a objetos do tipo “data”.▪Nenhum par de elementos possui a mesma

chave.▪Percurso é ordenado.▪ Indicada para implementação de dicionários.▪ Implementada por uma árvore balanceada

de busca (Red Black, Splay).▪Busca em O(log n).▪Descrição, Implementação.

• multimap é a versão que permite duplicatas.▪Descrição, Implementação.

Page 23: 2008 LCG/UFRJ. All rights reserved. 1 Standard Template Library STL Claudio Esperança Paulo Roma Cavalcanti

23

2008 LCG/UFRJ. All rights reserved.

Uso da classe Uso da classe mapmap..

#include <map>#include <string>#include <iostream>

using namespace std;

typedef map < long, string > mapType;typedef mapType::value_type ValuePair;

int main() {

mapType Map;

Map[836361136] = "Andrew"; Map[274635328] = "Berni"; Map[974635328] = "Ulisses"; Map[277735328] = "Paulo"; Map[277825328] = "Pedro"; Map[266735328] = "Peter"; Map[275734328] = "Paula"; Map[275839328] = "Paulos"; Map.insert(ValuePair(260736622, "John")); Map.insert(ValuePair(720002287, "Karen")); Map.insert(ValuePair(138373498, "Thomas")); Map.insert(ValuePair(135353630, "William")); // insertion of Xaviera is not executed, because // the key already exists. Map.insert(ValuePair(720002287, "Xaviera"));

mapType Map2 ( Map.begin(), Map.end() ); cout << "equality operator " << (Map2 == Map) << endl;

Duas formas de inserção

Chave e dado.

Cria um par

(chave,dado).

equality operator 1Output:974635328:Ulisses836361136:Andrew720002287:Karen277825328:Pedro277735328:Paulo275839328:Paulos275734328:Paula

Ordem decresce

nte.

Page 24: 2008 LCG/UFRJ. All rights reserved. 1 Standard Template Library STL Claudio Esperança Paulo Roma Cavalcanti

24

2008 LCG/UFRJ. All rights reserved.

Uso da classe Uso da classe mapmap..

cout << "Output:\n";

Map.erase ( 720002287 ); Map2.swap ( Map ); mapType::const_reverse_iterator iter = Map.rbegin(); while( iter != (mapType::const_reverse_iterator)Map.rend() ) { cout << (*iter).first << ':' << (*iter).second << endl; ++iter; }

cout << "Output of the name after entering the number\n" << "Number: "; long Number;

cin >> Number; mapType::const_iterator it = Map.find(Number);

if(it != Map.end()) { cout << (*it).second << ' ' // O(1)

<< endl; } else cout << "Not found!" << endl;}

Se encontra

do.

Busca é O(log n).

Iterador reverso.

Cast para

iterador constant

e.

274635328:Berni266735328:Peter260736622:John138373498:Thomas135353630:WilliamOutput of the name after entering the numberNumber: 275734328Paula

Page 25: 2008 LCG/UFRJ. All rights reserved. 1 Standard Template Library STL Claudio Esperança Paulo Roma Cavalcanti

25 2008 LCG/UFRJ. All rights reserved.

Hash MapHash Map

• hash_map associa objetos do tipo “key” a objetos do tipo “data”.▪ Nenhum par de elementos possui a mesma

chave.▪ Não há ordem de percurso.▪ Implementada por uma hash table.

◦ Há uma função de hash que gera endereços a partir de chaves.

▪ Busca em O(1).▪ Descrição, Implementação.

• hash_multimap é a versão que permite duplicatas.▪ Descrição, Implementação.

Page 26: 2008 LCG/UFRJ. All rights reserved. 1 Standard Template Library STL Claudio Esperança Paulo Roma Cavalcanti

26

2008 LCG/UFRJ. All rights reserved.

Uso da classe Uso da classe hash_maphash_map..

#include <ext/hash_map>#include <string>#include <iostream>

using namespace std;using __gnu_cxx::hash_map;using __gun_cxx::hash;

// initial hash table size#define table_size 11

// define your own hash functiontemplate <class T> class my_hash: public hash<T> {public:

my_hash() {}

size_t operator()(const string& p) const { hash<const char*> h; return h(p.c_str()); }}; typedef hash_map<string, string, my_hash<string> > mapType;typedef mapType::value_type ValuePair;

int main() {

mapType Map ( table_size, my_hash <string>() );

Map["ANDREW"]="Andrew"; Map["BERNI"]="Berni"; Map["JOHN"]="John"; Map.insert(ValuePair("KAREN", "Karen")); Map.insert(ValuePair("THOMAS", "Thomas")); Map["WILLIAM"]="William"; // insertion of Xaviera is not executed, because // the key already exists. Map.insert(ValuePair("BERNI", "Xaviera"));

Recebe string e passa char*.

Page 27: 2008 LCG/UFRJ. All rights reserved. 1 Standard Template Library STL Claudio Esperança Paulo Roma Cavalcanti

27

2008 LCG/UFRJ. All rights reserved.

Uso da classe Uso da classe hash_maphash_map..

cout << "Output:\n";

mapType::iterator iter = Map.begin(); while(iter != Map.end()) { cout << (*iter).first << ':' << (*iter).second << endl; ++iter; }

cout << "Output of the name after entering the key\n" << "Key: "; char buf[256]; buf[0] = '\0'; fgets ( buf, 256, stdin ); if ( buf[strlen(buf)-1]=='\n' ) buf[strlen(buf)-1] = '\0'; string key ( buf );

iter = Map.find(key);

if(iter != Map.end()) { cout << (*iter).second << ' '

<< Map[key] << endl;

} else cout << "Not found!" << endl;

}

Elimina \n do final de buf.

Busca é O(1)

Output:JOHN:JohnBERNI:BerniKAREN:KarenANDREW:AndrewTHOMAS:ThomasWILLIAN:WillianOutput of the name after entering the keyKey: KARENKaren Karen

Não há ordem.