1 / 41

S tandard T emplate L ibrary

S tandard T emplate L ibrary. Programowanie uogólnione, parametryczne ( generic programming) Składniki biblioteki STL kontenery iteratory algorytmy adaptatory funktory Nicolai M. Josuttis, C++ Biblioteka standardowa , Helion 2003. kontener. iterator.

derry
Download Presentation

S tandard T emplate L ibrary

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. StandardTemplateLibrary • Programowanie uogólnione, parametryczne • ( generic programming) • Składniki biblioteki STL • kontenery iteratory algorytmy adaptatory funktory • Nicolai M. Josuttis, C++ Biblioteka standardowa, Helion 2003 kontener iterator Algorytm iterator kontener iterator kontener

  2. WZORCE Wzorce funkcji template <class T> T minimum (T Pierwsza, T Druga) { return Pierwsza < Druga ? Pierwsza : Druga; } template <class T> bool greater (T Pierwsza, int Druga) { return Pierwsza > Druga; } // int a = 5; double x = -112.8; cout << minimum(a, -17) << endl; // wersja int cout << minimum(x, a); // błąd cout << minimum(x, (double)a) << endl; // wersja double cout << greater(a, 5) << endl; // wersja int, int cout << greater(x, a) << endl; // wersja double, int cout << greater(a, x) << endl; // wersja int, int

  3. Wzorce klas template <class T> class Para { T Lewy; T Prawy; int Numer; public: Para(int Nr): Numer(Nr) {} Para(T, T, int); ~Para(); int Wiekszy (T wzorzec); }; template <class T> Para <T> :: Para(T lewy, T prawy, int nr): Lewy(lewy), Prawy(prawy), Numer(nr) {cout << "Razem!" << endl;} template <class T> Para <T> ::~Para () { cout << "Rozwod!" << endl;} template <class T> int Para <T> :: Wiekszy (T wzorzec) { if (Lewy > wzorzec) return Numer; else return -1; }

  4. Para <int> ParaCalk(1, 2, 5); cout << ParaCalk.Wiekszy(7) << endl; cout << ParaCalk.Wiekszy(-4) << endl; float x=4.0, *px = &x; //Para <float> ParaRzecz(x, px, 5); // błąd Para<double>* WskPd = new Para<double>(3.0, 7.0, 9); cout << WskPd->Wiekszy(5.0) << endl; delete WskPd; Razem! -1 5 Razem! -1 Rozwod! Rozwod!

  5. Kontenery • Wektor • Kolejka o dwu końcach • Lista • Zbiór lub wielozbiór • Mapa lub multimapa sekwencyjne asocjacyjne

  6. Wektory #include"stdafx.h" #include<iostream> #include<vector> usingnamespace std; vector<int> coll; // kontener wektorowy dla liczb całkowitych // dołącz elementy o wartościach od 1 do 7 for (int i=1; i<=7; ++i) coll.push_back(i);// coll[i] = i : błąd // wyświetl wszystkie elementy rozdzielone spacjami for (int i=0; i < coll.size(); ++i) cout << coll[i] << ' '; 1 2 3 4 5 6 7

  7. Kolejki o dwu końcach (deque) #include <deque> deque<float> coll; // kontener deque dla elementów typu float // wstaw elementy o wartościach od 1.1 do 7.7 na początek kontenera for (int i=1; i<=7; ++i) { coll.push_front(i * 1.1f); // wstaw na początek } // wstaw elementy o wartościach od -1.1 do -7.7 na koniec kontenera for (int i=1; i<=7; ++i) { coll.push_back(i * -1.1f); // wstaw na koniec } // wyświetl wszystkie elementy rozdzielone spacjami for (int i=0; i <coll.size(); ++i) { cout << coll[i] << ' '; } 7.7 6.6 5.5 4.4 3.3 2.2 1.1 -1.1 -2.2 -3.3 -4.4 -5.5 -6.6 -7.7

  8. Listy #include <list> list<char> coll; // kontener list dla elementów znakowych // dolacz elementy od 'a' do 'z' for (char c='a'; c<='z'; ++c) { coll.push_back(c);// push_front(c) } /* wypisz wszystkie elementy : - gdy lista nie jest pusta - wypisz i usuń pierwszy element */ while (! coll.empty()) { cout << coll.front() << ' ';// coll.back() coll.pop_front();// pop_back() } a b c d e f g h i j k l m n o p q r s t u v w x y z

  9. Adaptatory kontenerów sekwencyjnych • Stos • #include <stack> • stack<int> st; • // wpisz trzy elementy na stos • st.push(1); st.push(2);st.push(3); • // ze stosu zdejmij i wypisz dwa elementy • cout << st.top() << ' '; st.pop(); • cout << st.top() << ' ';st.pop(); • cout << '\t'; • // zmodyfikuj szczytowy element • st.top() = 77; • // wpisz dwa nowe elementy • st.push(4); st.push(5); • // zdejmij jeden element nie przetwarzając go • st.pop(); • // zdejmij i wypisz pozostałe elementy • while (!st.empty()) • { • cout << st.top() << ' '; • st.pop(); • } 3 2 4 77

  10. Kolejka • #include <queue> • #include <string> • queue<string> q; • // do kolejki wstaw trzy elementy • q.push("Tu ");q.push("sa ");q.push("wiecej niz "); • // z kolejki odczytaj i wypisz dwa elementy • cout << q.front(); • q.pop(); • cout << q.front(); • q.pop(); • // wstaw dwa nowe elementy • q.push("cztery "); • q.push("slowa!"); • // opusc jeden element • q.pop(); • // odczytaj i wypisz pierwszy i ostatni element • cout << q.front() << endl; • cout << q.back() << endl; • // wypisz liczbe elementow w kolejce • cout << "liczba elementow w kolejce: " << q.size(); Tu sa cztery slowa! liczba elementow w kolejce: 2

  11. Kolejka priorytetowa #include <queue> priority_queue<double> q; // do kolejki priorytetowej wstaw trzy elementy q.push(66.6); q.push(22.2); q.push(44.4); // odczytaj i wypisz dwa elementy cout << q.top() << ' '; q.pop(); cout << q.top() << endl; q.pop(); // wstaw kolejne trzy elementy q.push(11.1); q.push(55.5); q.push(33.3); // pomin jeden element q.pop(); // zdejmij i wypisz pozostale elementy while (!q.empty()) { cout << q.top() << ' ';q.pop();} TaskQueue 66.6 44.4 33.3 22.2 11.1

  12. class Zadanie { int Priorytet; char* Opis; public: Zadanie(int, char* ); friendbooloperator < (Zadanie, Zadanie); // less friend ostream& operator << (ostream&, Zadanie&); }; Zadanie::Zadanie(int pr = 0, char* op = NULL) : Priorytet(pr), Opis(op){} booloperator < (Zadanie z1, Zadanie z2) { return z1.Priorytet < z2.Priorytet;} ostream& operator << (ostream& wy, Zadanie& zz) { wy << zz.Opis << " o priorytecie : "<< zz.Priorytet << endl; return wy; }

  13. priority_queue<Zadanie> ListaZadan;   ListaZadan.push(Zadanie(5, "Zad-1")); ListaZadan.push(Zadanie(12, "Zad-2")); ListaZadan.push(Zadanie(3, "Zad-3")); ListaZadan.push(Zadanie(7, "Zad-4")); cout << ListaZadan.top(); ListaZadan.pop();   ListaZadan.push(Zadanie(8, "Zad-5")); ListaZadan.push(Zadanie(4, "Zad-6")); cout << ListaZadan.top(); Zad-2 o priorytecie : 12 Zad-5 o priorytecie : 8

  14. Iteratory Iterator – obiekt, który służy do nawigowania w kontenerze Operatory dla interatorów: * -> ++ -- == != = Funkcje kontenerów związane z iteratorami begin( ) end( )

  15. Typy iteratorów • kontener::iterator nazwa // zapis i odczyt • kontener::const_iterator nazwa // tylko odczyt • dwukierunkowy ( ++ , -- ) : • list, set, multiset, map, multimap • dostępu swobodnego (arytmetyka iteratorów i dwukierunkowy) : • vector, deque

  16. list<char> coll; // kontener typu lista dla elementów znakowych // dolacz elementy od 'a' do 'z' for (char c='a'; c<='z'; ++c) coll.push_back(c); // wypisz wszystkie elementy - iteruj po wszystkich elementach list<char>::const_iterator pos; for (pos = coll.begin(); pos != coll.end(); ++pos) // tylko ++ -- cout << *pos << ' '; a b c d e f g h i j k l m n o p q r s t u v w x y z vector<char> vw; for (char c='a'; c<='z'; ++c) vw.push_back(c); vector<char> iterator lok; for (lok = coll.begin(); lok != coll.end(); lok += 2)// co drugi { *lok = toupper(*lok); cout << *lok << ' '; } ONP1 A C E G I K M O Q S U W Y

  17. Kontenery asocjacyjne Zbiory i wielozbiory typedef set<int> IntSet; // sort using less ( < ) IntSet coll; // kontener set dla wartości typu int // wstaw 7 elementów - wartość 1 wstawiana jest dwukrotnie coll.insert(3); coll.insert(1); coll.insert(5); coll.insert(4); coll.insert(1); coll.insert(6); coll.insert(2); coll.insert(7); // wypisz wszystkie elementy - iteruj po wszystkich elementach IntSet::const_iterator pos; for (pos = coll.begin(); pos != coll.end(); ++pos) cout << *pos << ' '; 1 2 3 4 5 6 7

  18. typedef multiset<int,greater<int> > IntMultSet; // sort using greater ( > ) IntMultSet cont; cont.insert(3); cont.insert(1); cont.insert(5); cont.insert(4); cont.insert(1); cont.insert(6); cont.insert(2);cont.insert(7); // wypisz wszystkie elementy - iteruj po wszystkich elementach IntMultSet::const_iterator lok; for (lok = cont.begin(); lok != cont.end(); ++lok) cout << *lok << ' '; 7 6 5 4 3 2 1 1

  19. Mapy i multimapy typedef multimap<int,string> IntStringMMap; IntStringMMap coll; // kontener na pary wartości typu int-string // wstaw kilka elementów w przypadkowej kolejności // - wartość o kluczu 1 wstawiana jest dwukrotnie coll.insert(make_pair(5,"oznakowanych")); coll.insert(make_pair(1,"jest")); coll.insert(make_pair(2,"multimapa")); coll.insert(make_pair(1,"to")); coll.insert(make_pair(4,"z")); coll.insert(make_pair(6,"łancuchów")); coll.insert(make_pair(3,"złożona")); /* wypisz wszystkie wartości elementów - iteruj po wszystkich elementach - druga składowa elementu to wartość */ IntStringMMap::iterator pos; for (pos = coll.begin(); pos != coll.end(); ++pos) cout << pos->second << ' '; jest to multimapa złożona z oznakowanych łancuchów

  20. /* typ kontenera: * - mapa: elementy o postaci par klucz-wartość * - string: klucze posiadają typ string * - float: wartości posiadają typ float */ typedef map<string,float> StringFloatMap; StringFloatMap coll; // wstaw do kolekcji kilka elementów – tablica asocjacyjna // (tylko mapy) coll["VAT"] = 0.22; coll["Pi"] = 3.1415; coll["dowolna liczba"] = 4983.223; coll["Zero"] = 0; /* wypisz wszystkie elementy - iteruj po wszystkich elementach - pierwsza składowa elementu to klucz - druga składowa elementu to wartość*/ StringFloatMap::iterator pos; for (pos = coll.begin(); pos != coll.end(); ++pos) cout << "klucz: \"" << pos->first << "\" " << "wartosc: " << pos->second << endl; MapFun2,1 klucz: "Pi" wartosc: 3.1415 klucz: "VAT" wartosc: 0.22 klucz: "Zero" wartosc: 0 klucz: "dowolna liczba" wartosc: 4983.22

  21. Algorytmy • funkcje globalne operujące na iteratorach • Zakresy • [ początek , koniec ) • początek - pozycja pierwszego elementu zakresu • koniec - pozycja następna za ostatnim elementem zakresu • #include <algorithm>

  22. list<int> coll; list<int>::iterator pos; for (int i=20; i<=40; ++i)coll.push_back(i);//elementy do 20 do 40 // ustal pozycje wartości 25 oraz 35 list<int>::iterator pos25, pos35; pos25 = find (coll.begin(), coll.end(), 25);// zakres, wartość pos35 = find (coll.begin(), coll.end(), 35);// zakres, wartość // wypisz największą wartość z odpowiedniego zakresu cout << "max: " << *max_element (pos25, pos35) << endl; // przetwarzaj elementy włącznie z ostatnią pozycją cout << "max: " << *max_element (pos25, ++pos35) << endl; max: 34 max: 35

  23. vector<int> coll; vector<int>::iterator pos; // wstaw elementy od 1 do 6 w przypadkowej kolejności coll.push_back(2); coll.push_back(5); coll.push_back(4); coll.push_back(1); coll.push_back(6); coll.push_back(3); // znajdź i wypisz elemento najmniejszej i największej wartości pos = min_element (coll.begin(), coll.end()); cout << "min: " << *pos << endl; pos = max_element (coll.begin(), coll.end()); cout << "max: " << *pos << endl; // zamień miejscami elementy z pozycji 3 i 5 swap( coll[3], coll[5] ); // od 0 // zamień miejscami element maksymalny i element ostatni swap( *pos, *(coll.end( )-1)); • min: 1 • max: 6

  24. // posortuj wszystkie elementy sort (coll.begin(), coll.end()); // znajdź pierwszy element o wartości 3 pos = find (coll.begin(), coll.end(), 3);// zakres wartość // odwróć kolejność elementów, począwszy od // znalezionego elementu o wartości 3do końca reverse (pos, coll.end()); // wypisz wszystkie elementy for (pos=coll.begin(); pos!=coll.end(); ++pos) { cout << *pos << ' '; } • 1 2 6 5 4 3

  25. Obsługa wielu zakresów • pierwszy zakres : początek i koniec • dalsze zakresy : tylko początek list<int> coll1; vector<int> coll2; for (int i=1; i<=9; ++i) coll1.push_back(i);// wstaw elementy od 1 do 9 // zmień rozmiar kolekcji 2 tak, // aby miała wystarczająco miejsca dla algorytmunadpisującego coll2.resize (coll1.size()); // utwórz trzecią kolekcję z wystarczająca ilością miejsca // - rozmiar początkowy przekazywany jest jako parametr deque<int> coll3(coll1.size());

  26. // przekopiuj elementy z pierwszej kolekcji do drugiej copy (coll1.begin(), coll1.end(), // źródło coll2.begin()); // przeznaczenie // przekopiuj elementy z drugiej kolekcji do trzeciej copy (coll2.begin(), coll2.end(), // źródło coll3.begin()); // przeznaczenie deque<int>::const_iterator lok; for (lok = coll3.begin(); lok != coll3.end(); ++ lok) cout << *lok << ' '; 1 2 3 4 5 6 7 8 9

  27. Adaptatory iteratorów • Iteratory wstawiające • wstawiacze końcowe • wstawiacze początkowe • wstawiacze ogólne

  28. list<int> coll1; // wstaw elementy od 1 do 9 do pierwszej kolekcji for (int i=1; i<=9; ++i) coll1.push_back(i); // przekopiuj elementy z coll1 do coll2 dołączając je na końcu vector<int> coll2; copy (coll1.begin(), coll1.end(), // źródło back_inserter(coll2)); // przeznaczenie // przekopiuj elementy z coll1 do coll3 wstawiając je na początku // - odwraca kolejność elementow deque<int> coll3; copy (coll1.begin(), coll1.end(), // źródło front_inserter(coll3)); // przeznaczenie deque<int>::const_iterator lok; for (lok = coll3.begin(); lok != coll3.end(); ++ lok) cout << *lok << ' ' ; 9 8 7 6 5 4 3 2 1

  29. // przekopiuj elementy z kolekcji coll1 do coll4 // - jedyny wstawiacz działający // w przypadku kolekcji asocjacyjnych set<int> coll4; copy (coll1.begin(), coll1.end(), // źródło inserter(coll4,coll4.begin())); // przeznaczenie set<int>::const_iterator pos; for (pos = coll4.begin(); pos != coll4.end(); ++ pos) cout << *pos << ' ' ; 1 2 3 4 5 6 7 8 9

  30. Iteratory strumieniowe list<int> coll; cout << "Wpisz ciag liczb całkowitych i zakończ go .Enter\n"; copy(istream_iterator<int>(cin),// początek źródła istream_iterator<int>(), // koniec źródła .Enter, ctrl-Z Enter front_inserter(coll)); // przeznaczenie // wypisz wszystkie elementy kolekcji copy (coll.begin(), coll.end(), // źródło ostream_iterator<int>(cout," ")); // przeznaczenie Wpisz ciag liczb całkowitych i zakończ go .Enter 12 34 56 78 90 . 90 78 56 34 12

  31. list<int> coll; for (int i=1; i<=6; ++i) { coll.push_front(i); coll.push_back(i); } // wypisz wszystkie elementy kolekcji copy (coll.begin(), coll.end(), ostream_iterator<int>(cout," ")); // usuń wszystkie elementy o wartości 3 remove (coll.begin(), coll.end(), 3); // wypisz wynikowe elementy kolekcji copy (coll.begin(), coll.end(), ostream_iterator<int>(cout," ")); 6 5 4 3 2 1 1 2 3 4 5 6 6 5 4 2 1 1 2 4 5 6 5 6

  32. coll.erase (coll.begin(), coll.end()); // usunięcie elementów for (int i=1; i<=6; ++i) { coll.push_front(i); coll.push_back(i); } // usuń wszystkie elementy o wartości 4- zachowaj nową pozycję końca list<int>::iterator end = remove (coll.begin(), coll.end(), 4); // wypisz wynikowe elementy kolekcji copy (coll.begin(), end, ostream_iterator<int>(cout," ")); // wypisz liczbę elementów wynikowych cout << "liczba usuniętych elementów: " << distance(end,coll.end()) << endl; // usuńunieważnione elementy coll.erase (end, coll.end()); // wypisz wszystkie elementy zmodyfikowanej kolekcji copy (coll.begin(), coll.end(), ostream_iterator<int>(cout," ")); 6 5 3 2 1 1 2 3 5 6 liczba usunietych elementow: 2 6 5 3 2 1 1 2 3 5 6

  33. Iteratory odwrotne vector<int> coll; // wstawia elementy od 1 do 9 for (int i=1; i<=9; ++i) coll.push_back(i); // wypisz wszystkie elementy w odwrotnej kolejności copy (coll.rbegin(), coll.rend(), // źródło ostream_iterator<int>(cout," ")); // przeznaczenie 9 8 7 6 5 4 3 2 1 WordHis, Trójki

  34. Funkcje Funkcje ogólne template <class T> inlinevoid PRINT_ELEMENTS (const T& coll, constchar* opis ="") { typename T::const_iterator pos; cout << opis; for (pos=coll.begin(); pos!=coll.end(); ++pos) { cout << *pos << ' '; } cout << endl; } // deque<int> coll2; PRINT_ELEMENTS(coll2,"Wartości początkowe : ");

  35. Funkcje jako argumenty algorytmów set<int> coll1; vector<int> coll2; // wstaw do kolekcji coll1 elementy od 1 do 9 for (int i=1; i<=9; ++i) { coll1.insert(i); } PRINT_ELEMENTS(coll1,"Wartości początkowe: "); // przekształć każdy element z coll1 i umieść go w coll2 // - podnieś do kwadratu przenoszone wartości transform (coll1.begin(),coll1.end(), // źródło back_inserter(coll2), // przeznaczenie square); // zdefiniowana operacja PRINT_ELEMENTS(coll2,"Podniesione do kwadratu : "); Wartosci poczatkowe : 1 2 3 4 5 6 7 8 9 Podniesione do kwadratu : 1 4 9 16 25 36 49 64 81

  36. Predykaty bool isPrime (int number) {if (number < 0) number = -number;// ignoruj znak ujemności if (number == 0 || number == 1) { returnfalse; } // liczby 0 i 1 nie są pierwszymi // znajdź dzielnik, przez który liczba dzieli się bez reszty int divisor; for (divisor = number/2; number%divisor != 0; --divisor){ } return divisor == 1; // gdyjest dzielnik większy od 1, liczba nie jest liczbą pierwszą }

  37. list<int> coll; // wstaw elementy od 24 do 30 for (int i=24; i<=30; ++i) { coll.push_back(i);} list<int>::iterator pos; pos = find_if (coll.begin(), coll.end(), // zakres isPrime); // predykat if (pos != coll.end()) {cout << *pos << " to pierwsza znaleziona liczba pierwsza" << endl; } else { cout << "Nie znaleziono żadnej liczby pierwszej" << endl;} 29 to pierwsza znaleziona liczba pierwsza

  38. Obiekty funkcyjne • mogą posiadać stan wewnętrzny (inicjowanie) • posiadają typ • działają szybciej niż zwykłe funkcje • // prosty obiekt funkcyjny, który wypisuje przekazany argument • class PrintInt • { • public: • voidoperator( ) (int elem) const • { • cout << elem << ' '; • } • };

  39. vector<int> coll; // wstaw elementy od 1 do 9 for (int i=1; i<=9; ++i) { coll.push_back(i); } // wypisz wszystkie elementy for_each (coll.begin(), coll.end(), // zakres PrintInt()); // operacja // konstruktor -> tempPrintIt ; // for_each -> tempPrintIt( *tempPos ) 1 2 3 4 5 6 7 8 9

  40. // obiekt funkcyjny dodający wartość, // którą został zainicjalizowany class AddValue {private: int theValue; // wartość do dodania public: AddValue(int v) : theValue(v) { } // konstruktor ustala wartość do dodania voidoperator() (int& elem) { elem += theValue; } // wywołanie funkcji dodaje wartość };

  41. list<int> coll; for (int i=1; i<=9; ++i)   // wstaw elementy od 1 do 9 { coll.push_back(i); } PRINT_ELEMENTS(coll,"wartości początkowe: "); // do każdego elementu dodaj wartość 10 for_each (coll.begin(), coll.end(), // zakres AddValue(10)); // operacja PRINT_ELEMENTS(coll,"po dodaniu liczby 10: "); // do każdego elementu dodaj wartość pierwszego elementu for_each (coll.begin(), coll.end(), // zakres AddValue(*coll.begin())); // operacja PRINT_ELEMENTS(coll,"po dodaniu pierwszego elementu: "); wartosci poczatkowe: 1 2 3 4 5 6 7 8 9 po dodaniu liczby 10: 11 12 13 14 15 16 17 18 19 po dodaniu pierwszego elementu: 22 23 24 25 26 27 28 29 30

More Related