Você está na página 1de 27

2008 LCG/UFRJ. All rights reserved.

1
Standard Template Library
STL
Claudio Esperana
Paulo Roma Cavalcanti
2008 LCG/UFRJ. All rights reserved.
2
O que a STL?
STL uma biblioteca padro com as
estruturas de dados mais usadas em
Computao.
Foi criada para evitar a implementao e teste
das mesmas estruturas de dados eternamente.
Por isso, economiza muito tempo e evita dor
de cabea desnecessria.
Por que templates?
Elas lhe poupam da tarefa de reimplementar o
cdigo para cada novo tipo de dado da sua
aplicao.
2008 LCG/UFRJ. All rights reserved.
3
STL
Quando usadas apropriadamente, as templates so
bastante eficazes.
No entanto, as mensagens de erro costumam ser
pouco elucidativas.
Uma boa fonte sobre a STL o guia de programao
da SGI.
Ou ento a nossa implementao de um subconjunto
da STL.
Na nossa implementao, cada classe tem o prefixo
utl (no havia namespace ainda).
Se a varivel de compilao USE_STL estiver
definida, o prefixo ser suprimido, cgcUtil:: ser
substitudo por std::, e o compilador usar a STL
nativa ento.
2008 LCG/UFRJ. All rights reserved.
4
Estrutura da STL
A STL oferece:
Containers (recipientes).
Iterators (iteradores).
Algorithms (algoritmos).
Recipientes servem para armazenar dados e
podem ser classificados como:
Seqncias de dados
Recipientes associativos para pares de objetos
(chave, dado).
Adaptadores que provem um subconjunto
da funcionalidade de um recipiente.
Pilhas, filas, filas de prioridade.


2008 LCG/UFRJ. All rights reserved.
5
Iteradores
Iteradores foram criados para permitir uma
maneira unificada de percorrer ou recuperar
dados de recipientes.
Escondem os detalhes de implementao,
principalmente ponteiros, das aplicaes.
Portanto, geralmente possvel trocar o tipo
de recipiente e ainda assim usar o mesmo
cdigo.
A STL adota a filosofia de manter os
algoritmos fora das classes dos recipientes.
A razo permitir que o mesmo algoritmo
possa agir sobre recipientes diferentes.

2008 LCG/UFRJ. All rights reserved.
6
Exemplo
Geralmente os algoritmos so
implementados usando iteradores apenas.
Ordenao, busca, contagem, substituio,
etc...
Iteradores tem operadores de incremento ++
definidos.
Ponteiros podem ser usados como iteradores.
2008 LCG/UFRJ.
All rights reserved.
7
Imprimindo
elementos de um
vetor
#include <vector>
#include <iostream>
using namespace std;

/** funo objeto.
* Insere T em um stream de sada.
* Substitui passar ponteiro para funo 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 7
6 objects printed.
Calcula o
tamanho de
A
Dois
iteradores
Redefine
operador ( )
Construtor
Guarda
nmero de
elementos
impressos
Chama print()
para cada
elemento de A
2008 LCG/UFRJ. All rights reserved.
8
Vector
vector o recipiente mais simples da STL.
uma seqncia que suporta acesso aleatrio
aos seus elementos.
Insero e remoo de elementos no final em
O(1).
Insero e remoo de elementos no meio em
O(n).
Busca em O(n).
Gerenciamento automtico de memria.
Iteradores esto invalidados aps realocao
de memria, insero e remoo no meio.
Descrio e implementao.
2008 LCG/UFRJ.
All rights reserved.
9
Uso da classe
vector.
#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
sada
Ordena V
com merge
sort.
Verifica se
V est
ordenado.
2008 LCG/UFRJ.
All rights reserved.
10
Funo 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 sada.
Derivados da
mesma classe
base.
2008 LCG/UFRJ. All rights reserved.
11
Deque
deque (Double Ended Queue) como um vetor com
insero eficiente na frente tambm.
uma seqncia que suporta acesso aleatrio aos
seus elementos.
Insero e remoo de elementos no meio em O(n).
Busca em O(n).
Insero e remoo de elementos na frente e no final
em O(1).
Gerenciamento automtico de memria.
Iteradores esto invalidados aps realocao de
memria, insero e remoo no meio.
Descrio e implementao.


2008 LCG/UFRJ.
All rights reserved.
12
Uso da classe deque.
#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 0
Q.insert(Q.begin() + 1, (size_t)3, 5);
Q.push_front(7);
Q.push_front(8);
Q.push_front(9);
Insere 5 trs
vezes aps a
primeira
posio.
2008 LCG/UFRJ.
All rights reserved.
13
Uso da classe deque.

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 0
9 8 7 1 5 5 5 2 0
9 8 7 1 5 5 5 2 0
98 99 9 8 7 1 5 5 5 2 0 88 88 88 88 88 88 88 88 88
88
9
9
Redimensiona
P completando
com 88 no final.
Remove os dois
primeiros
elementos de P.
ltimo
elemento de P
Primeiro
elemento de P
2008 LCG/UFRJ. All rights reserved.
14
List
list de fato uma lista duplamente
encadeada.
uma seqncia que suporta percurso para
frente e para trs.
Busca em O(n).
Insero e remoo de elementos na frente, no
meio e no final em O(1).
Iteradores ainda esto vlidos aps insero,
splicing ou remoo.
Descrio, Implementao.
2008 LCG/UFRJ.
All rights reserved.
15
Uso da classe list.
#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 0
1 2 1 2 0 0
Insere 0 no
final de L Insere 1 no
incio de L.
Insere 2
aps a
primeira
posio.
Move
elementos de
M para L.
M est
vazia.
2008 LCG/UFRJ. All rights reserved.
16
String
string toma o lugar de um array of char.
No mais necessrio se preocupar com o
tamanho do arranjo.
Oferece todas as funes de C pertinentes a
strings como membros da classe.
Evita erros relacionados com ponteiros, na
chamada de funes que recebem ou
retornam strings.
Descrio, Implementao.
2008 LCG/UFRJ.
All rights reserved.
17
Uso da classe string.
#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 = 0
const char constructor: hellow world!
data = hellow world!
size = 13
length = 13
capacity = 13
max_size = 13
str0 empty = 1
str1 empty = 0

Capacidade da
string sem ter
de realocar.
Tamanho mximo
que uma string
pode ter.
Comprimento
atual da string
O mesmo que
length.
2008 LCG/UFRJ.
All rights reserved.
18
Uso da classe string.
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 wor
char[], npos, str4 constructor: hellow
n, char str5 constructor: hhhhhhhhhhhh
str5 size = 12
swap str1 and str5
str1 = hhhhhhhhhhhh
str5 = hellow world!
Troca o
contedo de
str5 por str1.
2008 LCG/UFRJ. All rights reserved.
19
Set
set uma coleo ordenada de objetos do tipo
key sem duplicatas.
Operaes de conjunto como interseo, unio
e diferena so eficientes.
Implementado por uma rvore balanceada de
busca (Red Black, Splay).
Busca em O(log n).
Descrio, Implementao.
multiset a verso que permite duplicatas.
Descrio, Implementao.

2008 LCG/UFRJ.
All rights reserved.
20
Uso da classe set.
#include <set>
#include <iostream>
using namespace std;

/// funo objeto. Compara duas seqncias 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 s
1

lexicograficamente
menor que s
2

Construtor a
partir de dois
iteradores
2008 LCG/UFRJ.
All rights reserved.
21
Uso da classe set.
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.
2008 LCG/UFRJ. All rights reserved.
22
Map
map associa objetos do tipo key a objetos do
tipo data.
Nenhum par de elementos possui a mesma
chave.
Percurso ordenado.
Indicada para implementao de dicionrios.
Implementada por uma rvore balanceada de
busca (Red Black, Splay).
Busca em O(log n).
Descrio, Implementao.
multimap a verso que permite duplicatas.
Descrio, Implementao.
2008 LCG/UFRJ.
All rights reserved.
23
Uso da classe map.
#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 insero
Chave e dado.
Cria um par
(chave,dado).
equality operator 1
Output:
974635328:Ulisses
836361136:Andrew
720002287:Karen
277825328:Pedro
277735328:Paulo
275839328:Paulos
275734328:Paula
Ordem
decrescente.
2008 LCG/UFRJ.
All rights reserved.
24
Uso da classe map.
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
encontrado.
Busca
O(log n).
Iterador
reverso.
Cast para
iterador
constante.

274635328:Berni
266735328:Peter
260736622:John
138373498:Thomas
135353630:William
Output of the name after entering the number
Number: 275734328
Paula

2008 LCG/UFRJ. All rights reserved.
25
Hash Map
hash_map associa objetos do tipo key a objetos do
tipo data.
Nenhum par de elementos possui a mesma chave.
No h ordem de percurso.
Implementada por uma hash table.
H uma funo de hash que gera endereos a partir de
chaves.
Busca em O(1).
Descrio, Implementao.
hash_multimap a verso que permite duplicatas.
Descrio, Implementao.
2008 LCG/UFRJ.
All rights reserved.
26
Uso da classe
hash_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 function
template <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*.
2008 LCG/UFRJ.
All rights reserved.
27
Uso da classe
hash_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:John
BERNI:Berni
KAREN:Karen
ANDREW:Andrew
THOMAS:Thomas
WILLIAN:Willian
Output of the name after entering the key
Key: KAREN
Karen Karen
No h
ordem.

Você também pode gostar