STL - Standard Template Library

Reviews
Shared by: moneu
Stats
views:
19
rating:
not rated
reviews:
0
posted:
11/16/2008
language:
English
pages:
0
STL - Standard Template Library Autor: Błażej Chodarcewicz rainbow.mimuw.edu.pl/~bc189380/STL/ Dlaczego STL? Elastyczność Efektywność Łatwość nauki i prostota Dobra specyfikacja i dokumentacja Jak to działa? Containers Sequence Containers Tablica C Dodanie/usunięcie na początku Dodanie/usunięcie z końca Dodanie/usunięcie ze środka Dostęp do pierwszego elementu Dostęp do ostatniego elementu Dostęp do elementu w środku vector O(n) O(1) O(n) O(1) O(1) O(1) deque O(1) O(1) O(n) O(1) O(1) O(1) list O(1) O(1) O(1) O(1) O(1) O(n) N/a N/a N/a O(1) O(1) O(1) #include < iostream.h > #include < vector.h > int main () { vector v1; // Empty vector of doubles. v1.push_back (32.1); v1.push_back (40.5); for (int i = 0; i < v1.size (); i++) cout << v1[i] << " "; cout << endl; } Zobaczymy na ekranie: 32.1 40.5 #include int main (){ deque d; d.push_back(4); d.push_back(9); d.push_back(16); d.push_front(1); for (int i = 0; i < d.size (); i++) cout << "d[" << i << "] = " << d[i] << endl; cout << endl; d.pop_front (); d[2] = 25; for (i = 0; i < d.size (); i++) cout << "d[" << i << "] = " << d[i] << endl; return 0; } d[0] = 1 d[1] = 4 d[2] = 9 d[3] = 16 d[0] = 4 d[1] = 9 d[2] = 25 #include < iostream.h > #include < list.h > int array1 [] = { 9, 16, 36 }; int array2 [] = { 1, 4 }; int main () { list l1 (array1, array1 + 3); list l2 (array2, array2 + 2); list::iterator i1 = l1.begin (); l1.splice (i1, l2); list< int >::iterator i2 = l1.begin (); while (i2 != l1.end ()) cout << *i2++ << endl; return 0; } 1 4 9 16 36 Adaptacje kontenerów. Stack i queue można zaimplementować z użyciem trzech podstawowych ciągów. Adaptacja kolekcji dostarcza ograniczony interfejs do kolekcji. Adaptacje nie zawierają iteratorów. Deklaracja: stack > s; stack s; //domyślnie deque Stack Najlepiej używać z vector lub deque, można też z list, ale jest to nie najlepszy pomysł bool empty(); size_type size(); value_type& top(); const value_type& top(); void push(const value_type&); void pop(); queue  Najlepiej używać z deque lub list, można też użyć vector’a, ale jest to nie efektywne  bool empty();  size_type size();  value_type& front();  const value_type& front();  value_type& back();  const value_type& back();  void push(const value_type&);  void pop(); priority_queue  Jako argument bierze typ sekwencyjny oraz funkcję porównującą elementy  Najlepiej używać z vector’em lub deque (jeśli rozmiar jest mocno dynamiczny). Nie można używać list, bo niezbędny jest operator[].  Używa implementacji algorytmu kopcowego. priority_queue interfejs: bool empty(); size_type size(); value_type& top(); const value_type& top(); void push(const value_type&); void pop(); Kolekcje asocjacyjne. Uogólnienie kolekcji Najczęściej używane typ kluczy to String Implementacja jest efektywna Czym różnią się kolekcje asocjacyjne? Set: zawiera tylko klucze, operacje jak na zbiorze Multiset: jak set tylko, że może być wiele kopii elementów Map: zbiór par klucz, wartość Multimap: klucze mogą się powtarzać Przykład użycia map int main(){ map months; months["january"] = 31; months["february"] = 28; months["march"] = 31; months["april"] = 30; months["may"] = 31; months["june"] = 30; months["july"] = 31; months["august"] = 31; months["september"] = 30; months["october"] = 31; months["november"] = 30; months["december"] = 31; } struct ltstr{ bool operator()(const char* s1, const char* s2) const { return strcmp(s1, s2) < 0; } }; Przykład użycia multimap struct ltstr { bool operator()(const char* s1, const char* s2) const { return strcmp(s1, s2) < 0; } }; int main(){ multimap m; m.insert(pair("a", 1)); m.insert(pair("c", 2)); m.insert(pair("b", 3)); m.insert(pair("b", 4)); } Alokatory Zawierają funkcje alokacji i dealokacji pamięci Czarne skrzynki Rodzaje alokatorów. alloc pthread_alloc Domyślny alokator. Za zwyczaj ma najlepsze charakterystyki, jest thread-safe. Dla każdego wątku jest oddzielna pula pamięci. Można tego używać tylko jeśli system operacyjny wspiera wielowątkowość. Jest za zwyczaj szybszy od alloc. Problem fragmentacji. thread-safe. single_client_alloc Alokator dla programów jedno wątkowych. Nie jest malloc_alloc Alokator używający standardowej funkcji malloc. Jest thread-safe, ale dość powolny. Iteratory Uogólnienie wskaźników Służą do iteracji po elementach Są pośrednikami pomiędzy kolekcjami i algorytmami Możliwość pisania generycznych algorytmów Rodzaje iteratorów Input Iterator Output Iterator Forward Iterator Bidirectional Iterator Random Access Iterator Const Iterator Input Iterator Output Iterator Forward Iterator Biderictional Iterator Random Access Iterator Algorytmy STL Generyczne algorytmy oddzielają algorytm od danych „Nie zależą” od reprezentacji danych Operują na iteratorach Non-mutating  template UnaryFunction for_each(InputIterator first, InputIterator last, UnaryFunction f);  template iterator_traits::difference_type count(InputIterator first, InputIterator last, const EqualityComparable& value);  template InputIterator find(InputIterator first, InputIterator last, const EqualityComparable& value)  template bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2);  template ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); Przykład: int main() { int A[] = { 2, 0, 4, 6, 0, 3, 1, -7 }; const int N = sizeof(A) / sizeof(int); cout << "Number of zeros: " << count(A, A + N, 0) << endl; } Przykład: template struct print : public unary_function{ 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 P = for_each(A, A + N, print(cout)); cout << endl << P.count << " objects printed." << endl; } Mutating  OutputIterator copy(InputIterator first, InputIterator last, OutputIterator result);  void swap(Assignable& a, Assignable& b);  ForwardIterator2 swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2);  OutputIterator transform(InputIterator first, InputIterator last, OutputIterator result, UnaryFunction op);  void replace(ForwardIterator first, ForwardIterator last, const T& old_value, const T& new_value)  void fill(ForwardIterator first, ForwardIterator last, const T& value);  ForwardIterator remove(ForwardIterator first, ForwardIterator last, const T& value);  void reverse(BidirectionalIterator first, BidirectionalIterator last);  OutputIterator remove_copy(InputIterator first, InputIterator last, OutputIterator result, const T& value); Przykład: vector V(5); iota(V.begin(), V.end(), 1); list L(V.size()); copy(V.begin(), V.end(), L.begin()); assert(equal(V.begin(), V.end(), L.begin())); Algorytmy sortowania:  void sort(RandomAccessIterator first, RandomAccessIterator last);  void stable_sort(RandomAccessIterator first, RandomAccessIterator last);  bool is_sorted(ForwardIterator first, ForwardIterator last, StrictWeakOrdering comp)  OutputIterator merge(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result);  bool binary_search(ForwardIterator first, ForwardIterator last, const LessThanComparable& value);  ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, const LessThanComparable& value); Przykład: int A[] = {1, 4, 2, 8, 5, 7}; const int N = sizeof(A) / sizeof(int); sort(A, A + N); copy(A, A + N, ostream_iterator(cout, " ")); wynik: " 1 2 4 5 7 8" Algorytmy operujące na zbiorach  bool includes(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2);  OutputIterator set_union(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result);  OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result);  OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result); Przykład: inline bool lt_nocase(char c1, char c2) { return tolower(c1) < tolower(c2); } int main() { int A1[] = {1, 3, 5, 7, 9, 11}; int A2[] = {1, 1, 2, 3, 5, 8, 13}; char A3[] = {'a', 'b', 'b', 'B', 'B', 'f', 'h', 'H'}; char A4[] = {'A', 'B', 'B', 'C', 'D', 'F', 'F', 'H' }; const int N1 = sizeof(A1) / sizeof(int); const int N2 = sizeof(A2) / sizeof(int); const int N3 = sizeof(A3); const int N4 = sizeof(A4); Wynik: Intersection of A1 and A2: 1 3 5 Intersection of A3 and A4: a b b f h cout << "Intersection of A1 and A2: "; set_intersection(A1, A1 + N1, A2, A2 + N2, ostream_iterator(cout, " ")); cout << endl << "Intersection of A3 and A4: "; set_intersection(A3, A3 + N3, A4, A4 + N4, ostream_iterator(cout, " "), lt_nocase); cout << endl; } Algorytmy kopcowe  void push_heap(RandomAccessIterator first, RandomAccessIterator last);  void pop_heap(RandomAccessIterator first, RandomAccessIterator last);  void make_heap(RandomAccessIterator first, RandomAccessIterator last);  void sort_heap(RandomAccessIterator first, RandomAccessIterator last);  bool is_heap(RandomAccessIterator first, RandomAccessIterator last); Przykład: int main(){ int A[] = {1, 2, 3, 4, 5, 6}; const int N = sizeof(A) / sizeof(int); make_heap(A, A+N); cout << "Before pop: "; copy(A, A+N, ostream_iterator(cout, " ")); pop_heap(A, A+N); cout << endl << "After pop: "; copy(A, A+N-1, ostream_iterator(cout, " ")); cout << endl << "A[N-1] = " << A[N-1] << endl; } Wynik: Before pop: 6 5 3 4 2 1 After pop: 5 4 3 1 2 A[N-1] = 6 Obiekty funkcyjne (funktory) Obiekty, które mogą być wołana jak funkcje Zwykłe funkcje to też obiekty funkcyjne Operator () Modele: Generator, Unary Function, Binary Function Predicate, Binary Predicate Adaptacyjne obiekty funkcyjne Przykłady: vector V(100); generate(V.begin(), V.end(), rand); struct less_mag : public binary_function { bool operator()(double x, double y) { return fabs(x) < fabs(y); } }; vector V; ... sort(V.begin(), V.end(), less_mag()); Przykład: struct adder : public unary_function { adder() : sum(0) {} double sum; void operator()(double x) { sum += x; } }; vector V; ... adder result = for_each(V.begin(), V.end(), adder()); cout << "The sum is " << result.sum << endl; Przykład: list L; ... list::iterator new_end = remove_if(L.begin(), L.end(), compose2(logical_and(), bind2nd(greater(), 100), bind2nd(less(), 1000))); L.erase(new_end, L.end()); Gdzie szukać informacji?  http://www.sgi.com/tech/stl/ - implementacja STL firmy Silicon Graphics, Inc. (SGI)  http://www.informatik.hs-bremen.de/~brey/stlbe.html - książka "Designing Components with the C++ STL"  http://www.xraylith.wisc.edu/~khan/software/stl/STL.newbie.html - strona o STL z 1995 roku  http://www.cs.brown.edu/people/jak/proglang/cpp/stltut/tut.html prosty tutorial  http://www.cs.rpi.edu/~wiseb/xrds/ovp2-3b.html - krótki opis STL'a  http://pages.cpsc.ucalgary.ca/~kremer/STL/1024x768/index.html strona o STL'u Dziękuję za uwagę!

Related docs
Template STL
Views: 14  |  Downloads: 5
Standard Template Library (STL)
Views: 20  |  Downloads: 4
The Standard Template Library (STL)
Views: 5  |  Downloads: 2
THE C++STANDARD TEMPLATE LIBRARY (STL)
Views: 0  |  Downloads: 0
STL , , , and Templates
Views: 21  |  Downloads: 3
Introduction to the STL
Views: 12  |  Downloads: 1
Templates and the STL
Views: 17  |  Downloads: 3
Templates and STL
Views: 12  |  Downloads: 3
STL
Views: 6  |  Downloads: 0
Other docs by moneu
Hewlett Packard Co Ammendments and Bylaws
Views: 201  |  Downloads: 0
Form 4797 Sales of Business Property
Views: 593  |  Downloads: 3
Demand For Payment
Views: 263  |  Downloads: 6
Demand for Inspection of Books and Records
Views: 313  |  Downloads: 6
Amazoncom Ammendments and By laws
Views: 140  |  Downloads: 1
Non-Discrimination Policy
Views: 324  |  Downloads: 23
Dirty Joke Cheat
Views: 983  |  Downloads: 11
Schedule D (Form 1040) Capital Gains and Losses
Views: 6758  |  Downloads: 19
2006 Inst CT-1 (PDF) Instructions
Views: 242  |  Downloads: 1