linguagem de programação i - start [prof. carlos eduardo...
TRANSCRIPT
STL
STL é uma biblioteca padrão com as estruturas de dados mais usadas ◦ Criada para evitar a implementação e teste das mesmas estruturas de dados
◦ Economiza tempo e evita retrabalho
É a biblioteca padrão de C++ Padronizada pelo ANSI em 1997 Por que templates?
◦ Poupam da tarefa de reimplementar o código para cada novo tipo de dado da sua aplicação.
3
STL
Quando usados apropriadamente, templates são bastante eficazes. ◦ Porém, mensagens de erro STL costumam ser pouco elucidativas.
Uma boa fonte sobre a STL é o guia de programação da SGI
4
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.
5
Organização da STL
Containers
<vector> Array unidimensional do tipo T
<list> Lista duplamente ligada do tipo T
<deque> Lista ligada ‘double-ended’ do tipo T
<queue> Lista ligada do tipo T
<stack> Pilha do tipo T
<map> Array associativo do tipo T (red-black tree)
<set> Conjunto do tipo T
<bitset> Array de booleanos
Organização da STL
General Utilities
<utility> Operadores
<funcional> Funções
<memory> Funções para manipulação de memória
<ctime> Funções de C para manipulação de data e hora
Iterators
<iterator> Definição e suporte para Iterators
Algorithms
<algorithm> Algoritmos gerais
<cstdlib> bsearch() e qsort()
Organização da STL
Diagnostics
<exception> Definição da classe exception
<stdexception> Exceções da biblioteca padrão
<cassert> Diagnóstico de Erros
<cerrno> Tratamento de erro com as funções de C
Organização da STL
Strings
<string> string do tipo T
<cctype> Classificação de caracteres
<cwctype> Classificação de wide-caracters
<cstring> Funções de C para manipulação de strings
<cwchar> Funções de C para classificação de wide-caracters
<cstdlib> Mais funções de C para manipulação de strings
Organização da STL
Input/Output
<iosfwd> Declarações forward de facilidades de E/S.
<iostream> Objetos e operações padrões de E/S.
<ios> Classes bases de E/S.
<streambuf> Stream buffers.
<istream> Templates de stream de entrada.
<ostream> Templates de stream de saída.
<iomanip> Manipuladores.
<sstream> Stream para E/S com strings.
Organização da STL
Input/Output
<cstdlib> Classificação de caracteres e funções
<fstream> Streams para E/S com arquivos
<cstdio> printf() e scanf()
<cwchar> printf() e scanf() para wide characters
Language Suport
<locale> Representa diferenças culturais
<clocale> Funções de C para representar diferenças culturais
Organização da STL
Language Suport
<limits> Limites numéricos
<climits> Macros de C com os limites numéricos
<cfloat> Macros de C com os limites de ponto flutuante
<new> Gerenciamento de memória dinâmico
<typeinfo> Suporte para identificação de tipos em tempo de execução
<exception> Suporte para o tratamento de exceções
<cstddef> Suporte para a biblioteca da linguagem C
<cstdargs> Criação de funções com lista de argumentos variável
<csetjmp> Funções de C para manipulação de Pilhas
Organização da STL
Language Suport
<cstdlib> Finalização do programa
<ctime> Relógio (Clock) do sistema
<csignal> Manipulação de sinais em C
Numéricos
<complex> Números complexos e seus operadores
<valarray> Vetores numéricos e operações
<numeric> Operações numéricas generalizadas
<cmath> Funções matemáticas de C
<cstdlib> Geração de números aleatórios em C
STL - Iteradores
Criados para permitir uma maneira unificada de percorrer ou recuperar dados de recipientes. ◦ Escondem detalhes de implementação das
aplicações. Diminui o uso de ponteiros
◦ É 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. ◦ Permitir que o mesmo algoritmo possa agir sobre
recipientes diferentes.
14
STL - Iteradores
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.
15
STL - Iteradores 16
#include <vector>
#include <iostream>
using namespace std;
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;
}
As classes const_iterator
É um tipo utilizado para percorrer os containers da STL
Objetos deste tipo são ponteiros Cada container possui uma classe com
este nome; Para percorrer um container podemos
utilizar os métodos: ◦ begin() - Ponteiro para o início do container ◦ end() - Ponteiro para o fim do container
As classes const_iterator 18
int main() {
typedef vector<int> IntVector;
IntVector v;
v.push_back(10);
v.push_back(14);
v.push_back(0);
v.push_back(-8);
v.push_back(30);
// declara um iterator para um vetor
IntVector::const_iterator iter;
// percorre o vetor através de um iterator
for (iter = v.begin();
iter != v.end(); iter++) {
cout << *iter << " ";
}
cout << endl;
cin.get();
return 0;
}
19
STL - Vector
vector é o recipiente mais simples da STL. ◦ 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
STL - Vector 20
#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";
}
STL - Vector 21
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;
}
22
STL - List
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.
STL - List 23
#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, " "));
}
STL - List 24
#include <iostream>
#include <list>
using namespace std;
int main() {
list<string> l;
l.push_back("Hello, ");
l.push_back(“Bro! ");
l.push_back("Fine? ");
for (list<string>::const_iterator i = l.begin(); i != l.end(); ++i) cout << *i;
}
25
STL - Set
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).
multiset é a versão que permite duplicatas.
STL - Set 26
#include <set>
#include <iostream>
using namespace std;
struct ltstr // função objeto. Compara duas seqüências de caracteres.
{
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;
STL - Set 27
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;
}
28
STL - Map
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). multimap é a versão que permite
duplicatas.
STL - Map 29
#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;
STL - Map 30
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;
}
31
class cool
{
private: int serial;
private: string longname;
public: cool() {} // try to comment this out to see the error
public: cool(int i, string s)
{
serial = i;
longname = s;
}
public: int get_serial() { return serial; }
public: string get_name() { return longname; }
public: void set_name(string n) { longname = n; }
};
int main()
{
cool c(5,"Five Young Canibals");
cool d(8,"Eighteen");
map<string,cool> m; // This container stores pair of objects string and cool
// I mean: copies of the objects I give to it
map<string,cool*> m2; // One could store pointers to objects in a container
m["Five"]=c;
m["Eight"]=d;
m["new"] = cool(78,"New object"); // short for m.insert(m.begin,make_pair(const string("Eight"),d));
map<string,cool>::iterator i;
for (i=m.begin(); i!= m.end(); ++i)
cout << (*i).second.get_serial() << " " << (*i).second.get_name() << endl;
// elements in the map are pairs, whose fields are first and second
cout << “One of the elements: " << m["new"].get_name() << endl;
}
32
STL - Hash 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).
hash_multimap é a versão que permite duplicatas.
33
#include <ext/hash_map> #include <string> #include <iostream> using namespace std; using __gnu_cxx::hash_map; using __gun_cxx::hash; #define table_size 11 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"; Map.insert(ValuePair("BERNI", "Xaviera"));
STL – Hash Map 34
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;
}
35
class cool
{
private: int serial;
private: string longname;
public: cool() {} // try to comment this out to see the error
public: cool(int i, string s)
{
serial = i;
longname = s;
}
public: int get_serial() { return serial; }
public: string get_name() { return longname; }
public: void set_name(string n) { longname = n; }
};
int main()
{
char *five="Five";
cool c(5,"Five Young Canibals");
cool d(8,"Eighteen");
hash_map<char*,cool> m;
m[five]=c;
m["Eight"]=d;
// short for m.insert(m.begin,make_pair(const string("Eight"),d));
hash_map<char*,cool>::iterator i;
cool x = m["Five"];
cout << x.get_serial() << " " << x.get_name() << endl;
// elements in the map are pairs, whose fields are first and second
char a;
cout << "Ok?";
cin >> a;
}
36
STL - String
string toma o lugar de um “array of char” (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.
37
#include <string>
#include <iostream>
using namespace std;
int main () {
string str0;
cout << "empty constructor: " << str0 << endl;
cout << "str0 size = " << str0.size() << endl;
string str1("hellow world!");
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;
cout << "str0 empty = " << str0.empty() << endl;
cout << "str1 empty = " << str1.empty() << endl;
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;
}
Strings 38
int main() {
string s;
// também é uma string
basic_string<char> bs;
// lê uma linha
getline(cin, bs);
cout << "bs = \"" << bs << "\"" << endl;
// lê uma string
cin >> s;
cout << "s = \"" << s << "\"" << endl;
// troca os conteúdos
s.swap(bs);
cout << "Apos a inversao: " << endl
<< "bs = \"" << bs << "\"" << endl
<< "s = \"" << s << "\"" << endl;
int a = s.find('a');
cout << "Primeiro indice da letra 'a' em s: " << a << endl;
s[a] = 'A';
cout << "Apos a modificacao s = \"" << s << "\"" << endl;
// converte s para uma strig de c
const char *p = s.data(); // s.c_str();
cout << "p = \"" << p << "\""<< endl;
cout << "Tamanho de bs: " << bs.length() << endl;
// limpa bs
bs = "";
cout << "bs foi limpa? " << (bs.empty() ? "Sim" : "Nao") << endl;
return 0;
}
Exercícios
Crie uma função verificarPalindromo() que recebe um vetor como parâmetro. Ela deve retornar true se ele contém um palíndromo e false caso contrário. ◦ Exemplo: Um vetor contendo 1, 2, 3, 2, 1 é um palíndromo.
E um vetor contendo 1, 4, 3, 2, 1 não é um palíndromo.
Crie uma mapa que associa o nome de uma pessoa a um objeto do tipo Pessoa. A classe Pessoa deve ser feita usando templates, armazenando uma variável de tipo arbitrário. Crie um programa que leia entradas e armazene utilizando a classe map. Caso o usuário tente cadastrar uma chave duplicada, uma exceção deve ser lançada.
39
Referências
Notas de aula – Claudio Esperança e Paulo Cavalcanti (UFRJ)
Notas de aula – Allan Lima (citi/UFPE)
41
Próximas aulas
STL
Programação Orientada a Eventos
Programação concorrente (Threads) ◦ (3ª. Prova)
43