11. března 2015, Brno Připravil: David Procházka Šablony, kontejnery a iterátory Programovací jazyk C++
Šablony Strana 2 / 31 Obsah přednášky 1 Šablony 2 Abstraktní datové struktury 3 Iterátory 4 Array 5 Kontejnery 6 Asociativní kontejnery 7 Další nástroje STL
Šablony Strana 3 / 31 Šablona funkce/metody Šablona je obecný popis (třídy, funkce) bez toho, že by byl specifikován konkrétní typ. Ten je dosazen podle potřeby až při použití šablony. Jedná se o specifikum jazyka C++. Implementaci metod, které obsahují šablonu je nutné psát do hlavičkového souboru. 1 template <class T> void prohod (T &a, T &b){ 2 T pom = a; 3 a = b; 4 b = pom ; 5 }
Šablony Strana 4 / 31 Použití šablony 1 template <class T> void prohod (T &a, T &b){ 2 T pom = a; 3 a = b; 4 b = pom ; 5 } 6 7 int main (){ 8 int a = 10; 9 int b = 11; 10 prohod (a, b); 11 cout << " A: " << a << endl ; 12 cout << " B: " << b << endl ; 13...
Šablony Strana 5 / 31 Šablony tříd 1 template < class T > class Sachovnice { 2 private : 3 T deska [8][8]; 4 public : 5 void vypln ( T prvek ){ 6 for ( int i =0; i <8; i ++) 7 for ( int j =0; j <8; j ++) 8 deska [i][j] = prvek ; 9 } 10 };
Šablony Strana 6 / 31 Použití šablony třídy 1 Sachovnice < int >* pokus = new Sachovnice < int >; 2 pokus -> vypln (0); 3 4 Sachovnice < float > pokus2 ; 5 pokus2. vypln (0.1); 6 7 delete pokus ;
Šablony Strana 7 / 31 Šablony o více parametrech 1 template < class T1, class T2 > class Sachovnice { 2 private : 3 T1 deska [8][8]; 4 T2 pomocnadeska [8][8]; 5 public : 6 void vypln ( T1 prvek ){ 7 for ( int i =0; i <8; i ++) 8 for ( int j =0; j <8; j ++) 9 deska [i][j] = prvek ; 10 } 11... 12 Sachovnice < int, char > pokus3 ;
Šablony Strana 8 / 31 Implicitní parametry 1 template < class T = int > 2 class Sachovnice {...}; 3 4 template < class T1, class T2 = int > 5 class JinaSachovnice {...}; 6 7 Sachovnice < > pokus ; 8 Sachovnice < int > pokus2 ; 9 10 JinaSachovnice < int > pokus ; 11 JinaSachovnice < int, char > pokus2 ;
Šablony Strana 9 / 31 Implementace šablony v podobě třídy Hlavičkový soubor: 1... 2 template < class T > class Sachovnice { 3... 4 }; 5 6 template < class T > Sachovnice <T >:: Sachovnice (){ 7... 8 } 9... Implementace metod jsou v hlavičkovém souboru! Implementační soubor: 1 # include " sachovnice.h"
Abstraktní datové struktury Strana 10 / 31 Obsah přednášky 1 Šablony 2 Abstraktní datové struktury 3 Iterátory 4 Array 5 Kontejnery 6 Asociativní kontejnery 7 Další nástroje STL
Abstraktní datové struktury Strana 11 / 31 ADT: Vector STL: Standard Template Library je knihovna šablon, která je součástí C++. Obsahuje implementace řady běžných ADT a algoritmů. Typickým zástupcem ADT z STL je šablona vector. std::vector je jednorozměrné dynamické pole bez specifikovaného typu.
Abstraktní datové struktury Strana 12 / 31 Příklad operací s kontejnerem std::vector 1 # include < vector > 2 # include < iostream > 3 4 int main () { 5 std :: vector <int > a (7); // Pole 7 cisel 6 std :: vector < int > b; // Pole 0 cisel 7 8 std :: cout << " Pocet prvku a je " << a. size (); 9 std :: cout << " Pocet prvku b je " << b. size (); 10 11 for ( int i = 0; i < a. size (); i ++){ 12 a. at( i) = 10; // vyhazuje vyjimku out_ of_ range 13 a[i] = 10; // nekontroluje rozsah 14 std :: cout << "a[" << i << "] = " << a.at(i) << " " 15 } 16 b = a; // Bez problemu lze pouzit operator = 17...
Abstraktní datové struktury Strana 13 / 31 Přidávání a ubírání prvků 1 std :: vector <int > a; 2 for ( int i = 0; i < 5; i ++){ 3 a. push_back (42); 4 std :: cout << " Posledni prvek je: " << a. back (); 5 } 6 7 for ( int i = 0; i < a. size (); i ++) { 8 std :: cout << a.at(i) << \t ; 9 } 10 11 while (!a. empty ()) { // Opakuj, dokud nema 0 prvku 12 a. pop_ back (); // Odeberu posledni prvek 13 } 14 15 std :: cout << " Velikost " << a. size () << std :: endl ;
Abstraktní datové struktury Strana 14 / 31 Vícerozměrné pole 1 std :: vector < std :: vector <int >> matice (3); //3x0 2 for ( int a = 0; a < 3; a ++) { 3 matice.at(a). push_back (a +1); 4 matice.at(a). push_back (a +2); 5 matice.at(a). push_back (a +3); 6 } 7 // Nyni mame matici 3 x 3, tupa metoda! 8 // Vymyslete elegantnejsi! 9 10 for ( int y = 0; y < 3; y ++){ 11 for ( int x = 0; x < 3; x ++){ 12 std :: cout << matice.at(x). at(y) << \t ; 13 } 14 std :: cout << std :: endl ; 15 }
Iterátory Strana 15 / 31 Obsah přednášky 1 Šablony 2 Abstraktní datové struktury 3 Iterátory 4 Array 5 Kontejnery 6 Asociativní kontejnery 7 Další nástroje STL
Iterátory Strana 16 / 31 Iterátory Iterátor je de facto ukazatel pro kontejner. Význam iteratorů spočívá v tom, že unifikují přístup k různým strukturám. Bez nich by nebylo možné vytvářet generické algoritmy. Bezpečnejší než indexy nebo ukazatele. Ke kontejnerům jsou předdefinovány užitečné iterátory na začátek (.begin()), za konec (.end()), atp. Iterátorů je celá řada (vstupní, výstupní, aj.).
Iterátory Strana 17 / 31 Průchod polem pomocí iterátorů 1 # include < vector > 2 3 std :: vector <int > pole (20); 4 for ( std :: vector <int >:: iterator temp = pole. begin (); 5 temp!= pole. end (); temp ++){ 6 * temp = 0; 7 } vectorem lze procházet i pomocí [] nebo metody at(). Doporučena je raději metoda at(), protože v případě vstupu na neplatnou pozici vyhodí výjimku std::out of range. Velmi elegantně lze využít v tomto případě typ auto.
Iterátory Strana 18 / 31 Využití iterátorů pro změny ve vectoru 1 // Vlozim pred prvni prvek -100 2 v1. insert (v1. begin (), -100); 3 // Vlozim na konec 3 krat 500 4 v1. insert (v1.end (),3,500); 5 // Vlozim cely vektor v1 do v2 6 v2. insert (v2. begin ()+2, v1. begin (), v1.end ()); 7 8 // Mazu prvek pod iteratorem 9 v2. erase (it ); 10 // Mazu vsechny prvky ve v2 11 v2. erase (v2. begin (), v2.end ()); 12 v2. clear ();
Array Strana 19 / 31 Obsah přednášky 1 Šablony 2 Abstraktní datové struktury 3 Iterátory 4 Array 5 Kontejnery 6 Asociativní kontejnery 7 Další nástroje STL
Array Strana 20 / 31 Array: náhrada pole 1 # include < iostream > 2 # include < array > 3 4 int main (){ 5 // inicializace pole 6 std :: array <int, 5> pole {0,1,2,3,4}; 7 std :: array <int, 5> pole2 = {0,1,2,3,4}; 8 // pristup na pozici 9 pole.at (0) = 10; 10 std :: cout << pole2.at (0) << std :: endl ; 11 // pruchod pole, lze i iteratory 12 for ( auto & cislo : pole ) std :: cout << cislo << " "; 13 std :: cout << std :: endl ; 14 // kontrola velikosti, lze i empty () 15 std :: cout <<" Velikost : " << pole. size () <<std :: endl ; 16...
Kontejnery Strana 21 / 31 Obsah přednášky 1 Šablony 2 Abstraktní datové struktury 3 Iterátory 4 Array 5 Kontejnery 6 Asociativní kontejnery 7 Další nástroje STL
Kontejnery Strana 22 / 31 Další kontejnery a jejich funkce Kontejnery většinou podporují insert, erase a clear. základní array pouze čtení a zápis kamkoliv základní vector front, back, push/pop back, at/[] (forward )list vector bez at/[]+ push/pop front deque vector + push front, pop front kontej. queue push,pop,front,back,size,empty adaptéry stack push, top, pop, size, empty priority que queue asoc. set 1 kontej. map multiset multimap 1 Od C++11 také unordered set, multiset, map, multimap
Kontejnery Strana 23 / 31 Základní rozdíl mezi kontejnery array (C++11) Nádrada C-like polí. Rychlý přísup k konstantním čase. Nelze měnit velikost. vector Prvky musí být za sebou v paměti rychlé čtení odkudkoli. Umožňuje rychlé mazání a přidávání na konec (pokud není potřeba realokace). Pomalé mazání z ostatních míst vektoru (lineární čas, musíme seznam posunout).
Kontejnery Strana 24 / 31 Základní rozdíl mezi kontejnery list Prvky nemusí být za sebou v paměti. Umožňuje vkládat prvek v konstantním čase (jakmile je pozice nalezena). Pomalý přístup po čtení (lineární čas, musíme projít). forward list (C++11) Zabere méně paměti než list. Podporuje pouze průchod od čela. deque Umožňuje přístup v konstantní čase pro čtení. Lze v konstantním čase přidávat na oba konce nebo odbírat. Vhodná nádrada vectoru, pokud je nutné měnit oba konce.
Asociativní kontejnery Strana 25 / 31 Obsah přednášky 1 Šablony 2 Abstraktní datové struktury 3 Iterátory 4 Array 5 Kontejnery 6 Asociativní kontejnery 7 Další nástroje STL
Asociativní kontejnery Strana 26 / 31 Asociativní kontejnery Jedná se o setříděné kontejnery, ale nechápeme je obvykle jako klasická pole hodnot. Strukturou lze však klasicky sekvenčeně projít. set je množina. map je hash, kde prvek je (místo pozice) identifikován klíčem. Ke klíči se vztahuje příslušná hodnota. multi varianty kontejnerů umožňují duplicitní prvky/klíče. unordered varianty jsou pro nesetříděné struktury. Mohou být rychlejší.
Asociativní kontejnery Strana 27 / 31 Asoc. kontejner set 1 # include <set > 2 # include < iterator > 3... 4 std :: multiset <int > mnozina ; 5 6 mnozina. insert (4); 7 mnozina. insert (3); 8 mnozina. insert (5); 9 10 std :: multiset <int >:: iterator pos ; 11 for ( pos = mnozina. begin (); pos!= mnozina. end (); ++ pos ){ 12 cout << * pos << ; 13 }
Asociativní kontejnery Strana 28 / 31 Asoc. kontejner map (hash) 1 # include <map > 2... 3 std :: map < string, string > slova ; 4 5 // ulozeni hodnoty 6 slova [" jmeno "] = " david "; 7 slova [" prijmeni "] = " prochazka "; 8 // vypis hodnoty 9 std :: cout << " Jmeno :" << slova [" jmeno "]; 10 // vypis velikost 11 std :: cout << " Velikost :" << slova. size (); 12 13 // vlozeni celeho paru hodnot 14 // nezbytne pro multimap, protoze klice jsou duplic. 15 slova. insert ( 16 std :: pair < string, string >(" jmeno "," hodnota " ));
Asociativní kontejnery Strana 29 / 31 Průchod mapem 1 2 // projdu v cyklu for a vypisuji klic ( first ) 3 // a hodnotu ( second ) 4 for ( std :: map < string, string >:: iterator it = 5 slova. begin (); it!= slova. end (); it ++) { 6 std :: cout << it -> first << " " << it -> second << " "; 7 }
Další nástroje STL Strana 30 / 31 Obsah přednášky 1 Šablony 2 Abstraktní datové struktury 3 Iterátory 4 Array 5 Kontejnery 6 Asociativní kontejnery 7 Další nástroje STL
Další nástroje STL Strana 31 / 31 Další nástroje STL Funktory (equal to<int>(a, b), greater, less,...), kopírování, náhrady, generátory, vyhledávání (find(v.begin(), v.end(), 4)), třídění (sort(v.begin(), v.end()),...