7. října 2010, Brno Připravil: David Procházka Šablony, kontejnery a iterátory Programovací jazyk C++
Šablony Strana 2 / 21 Š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++. 1 template <class T> void prohod (T &a, T &b){ 2 T pom = a; 3 a = b; 4 b = pom ; 5 }
Šablony Strana 3 / 21 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 4 / 21 Š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 5 / 21 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 6 / 21 Š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 7 / 21 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 ;
STL Strana 8 / 21 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. vector je jednorozměrné dynamické pole bez specifikovaného typu.
STL Strana 9 / 21 Příklad operací s kontejnerem vector 1 # include < vector > 2 # include < iostream > 3 using namespace std ; 4 int main () { 5 vector <int > a (7); // Pole 7 čísel 6 vector < int > b; // Pole 0 čísel 7 cout << " Počet prvků a je " << a. size () << " "; 8 cout << " Počet prvků b je " << b. size () << endl ; 9 for ( int i = 0; i < a. size (); i ++){ 10 a[i] = i + 1; 11 cout << "a[" << i << "] = " << a[i] << endl ; 12 } 13 b = a; // Bez problémů lze použít operátor = 14...
STL Strana 10 / 21 Přidávání a ubírání prvků 1 vector <int > a; 2 for ( int i = 0; i < 5; i ++){ 3 a. push_back (i +1); 4 cout << " Poslední prvek je: " << a. back () << endl ; 5 } 6 7 for ( int i = 0; i < a. size (); i ++) { 8 cout << a[i] << \t ; 9 } 10 11 while (!a. empty ()) { // Opakuj, dokud nemá 0 prvků 12 a. pop_ back (); // Odeberu poslední prvek 13 } 14 15 cout << " Velikost " << a. size () << endl ;
STL Strana 11 / 21 Vícerozměrné pole 1 vector < vector <int > > matice (3); // Matice 3x0 2 for ( int a = 0; a < 3; a ++) { 3 matice [a]. push_back (a +1); 4 matice [a]. push_back (a +2); 5 matice [a]. push_back (a +3); 6 } // Nyní máme matici 3 x 3, tupa metoda! 7 8 for ( int y = 0; y < 3; y ++){ 9 for ( int x = 0; x < 3; x ++){ 10 cout << matice [x][y] << \t ; 11 } 12 cout << endl ; 13 }
Iterátory Strana 12 / 21 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 13 / 21 Průchod polem pomocí iterátorů 1 # include < vector > 2 3 vector <int > vektor (20); 4 for ( vector < int >:: iterator temp = vektor. begin (); 5 temp!= vektor. 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 out of range.
Iterátory Strana 14 / 21 Využití iterátorů pro změny ve vectoru 1 // Vložím před první prvek -100 2 v1. insert (v1. begin (), -100); 3 // Vložím na konec 3 krát 500 4 v1. insert (v1.end (),3,500); 5 // Vložím celý vektor v1 do v2 6 v2. insert (v2. begin ()+2, v1. begin (), v1.end ()); 7 8 // Mažu prvek pod iterátorem 9 v2. erase (it ); 10 // Mažu všechny prvky ve v2 11 v2. erase (v2. begin (), v2.end ()); 12 v2. clear ();
Kontejnery Strana 15 / 21 Další kontejnery a jejich funkce Všechny posloupnosti podporují popsané varianty insert, erase a clear. Navíc mají další metody. jednoduché vector front, back, push/pop back, at/[] list vector bez at/[]+ push/pop front deque vector + push front, pop front kontejner. queue push,pop,front,back,size,empty adaptéry stack push, top, pop, size, empty priority que queue asociativní set kontejnery map multiset multimap
Kontejnery Strana 16 / 21 Komentáře k tabulce list i deque umožňují narozdíl od vectoru vkládat na začátek/mazat ze začátku prvek v konstantním čase. Proto jsou u nich tyto metody implementovány. U vectoru by tato operace měla linerární složitost (posun všech prvků dozadu). vector i deque nabízí přímý přístup s lineární složitostí. vector je ale jednodužší a proto rychlejší. list je naopak zaměřen na rychlé vkládání a mazání prvků kdekoliv v konstantním čase. priority queue je stejná jako queue jen prvek s největší hodnotou se dostane automaticky do čela fronty.
Asociativní kontejnery Strana 17 / 21 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.
Asociativní kontejnery Strana 18 / 21 Asoc. kontejner set 1 # include <set > 2 # include < iterator > 3... 4 multiset < int > mnozina ; 5 6 mnozina. insert (4); 7 mnozina. insert (3); 8 mnozina. insert (5); 9 10 multiset < int >:: iterator pos ; 11 for ( pos = mnozina. begin (); pos!= mnozina. end (); ++ pos ){ 12 cout << * pos << ; 13 }
Asociativní kontejnery Strana 19 / 21 Asoc. kontejner map (hash) 1 # include <map > 2... 3 map < string, string > slova ; 4 5 // ulozeni hodnoty 6 slova [" jmeno "] = " david "; 7 slova [" prijmeni "] = " prochazka "; 8 // vypis hodnoty 9 cout << " Jmeno : " << slova [" jmeno "] << endl ; 10 // vypis velikost 11 cout << " Velikost : " << slova. size () << endl ; 12 // vlozeni celeho paru hodnot 13 slova. insert (pair < string, string >(" jmeno "," hodnota " ));
Asociativní kontejnery Strana 20 / 21 Průchod mapem 1 2 // projdu v cyklu for a vypisuji klic ( first ) 3 // a hodnotu ( second ) 4 for ( map < string, string >:: iterator iter = freq. begin (); 5 iter!= freq. end (); ++ iter ) { 6 cout << iter - > first << " " << iter - > second << endl ; 7 }
Další nástroje STL Strana 21 / 21 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()),...