PB161 Programování v jazyce C++ Přednáška 6



Podobné dokumenty
PB přednáška (26. října 2015)

PB161 Programování v jazyce C++ Přednáška 3

PB161 Programování v jazyce C++ Přednáška 3

Šablony, kontejnery a iterátory

Šablony, kontejnery a iterátory

Standardní algoritmy vyhledávací.

Funkční objekty v C++.

Jazyk C++ II. STL knihovna kontejnery část 2

Jazyk C++ II. STL knihovna kontejnery část 1

PB161 Programování v jazyce C++ Přednáška 9

PB161 Programování v jazyce C++ Přednáška 10

PROGRAMOVÁNÍ V C++ CVIČENÍ. Michal Brabec

Množina v C++ (set, multiset).

map, multimap - Asociativní pole v C++.

Množina čísel int stl-set-int.cpp

PB161 Programování v jazyce C++ Přednáška 4

PB161 Programování v jazyce C++ Přednáška 10

Šablony funkcí a tříd (Templates) Genericita

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Abstraktní datové typy

Kolekce, cyklus foreach

Základní datové struktury

PB161 Programování v jazyku C++

Iterátory v C++. int pole[20]; for (int *temp = pole, temp!= &pole[20]; temp++) { *temp = 0;

OBJEKTOVÉ PROGRAMOVÁNÍ V C++ V PŘÍKLADECH 8 Proudová knihovna 8.1 Hierarchie proudů Standardně zavedené proudy

Hornerovo schéma. je algoritmus výpočtu hodnoty polynomu P(x) v bodě x 0. eliminuje výpočet i-té mocniny převodem na postupné násobení.

Seznamy a iterátory. Kolekce obecně. Rozhraní kolekce. Procházení kolekcí

Pokročilé programování v jazyce C pro chemiky (C3220) Statické proměnné a metody, šablony v C++

Dynamické datové struktury I.

Vector datový kontejner v C++.

Hrátky s funkcemi. PV173 Programování v C++11. Vladimír Štill, Jiří Weiser. Fakulta Informatiky, Masarykova Univerzita. 29.

boolean hasnext() Object next() void remove() Kolekce

Datové typy v Javě. Tomáš Pitner, upravil Marek Šabo

PB161 Programování v C++ Proudy pro standardní zařízení Souborové proudy Paměťové proudy Manipulátory

Standardní algoritmy v C++.

Programování v C++ 1, 5. cvičení

Úvod do programování 6. hodina

přetížení operátorů (o)

5. Vyhledávání a řazení 1

Dynamické datové struktury IV.

Spojová implementace lineárních datových struktur

Jazyk C++ II. Šablony a implementace

Programování v C++, 2. cvičení

Fronta (Queue) Úvod do programování. Fronta implementace. Fronta implementace pomocí pole 1/4. Fronta implementace pomocí pole 3/4

Da D to t v o é v ty t py IB111: Datové typy

Základní pojmy. Úvod do programování. Základní pojmy. Zápis algoritmu. Výraz. Základní pojmy

Martin Flusser. Faculty of Nuclear Sciences and Physical Engineering Czech Technical University in Prague. October 17, 2016

Jazyk C++ I. Šablony

Pokročilé programování v jazyce C pro chemiky (C3220) Operátory new a delete, virtuální metody

Vyhledávání. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava. Prezentace ke dni 21.

Spojový seznam. Jan Kybic.

ADT/ADS = abstraktní datové typy / struktury

int ii char [16] double dd název adresa / proměnná N = nevyužito xxx xxx xxx N xxx xxx N xxx N

Více o konstruktorech a destruktorech

Dynamicky vázané metody. Pozdní vazba, virtuální metody

Programování v C++ 2, 4. cvičení

IAJCE Přednáška č. 9. int[] pole = new int[pocet] int max = pole[0]; int id; for(int i =1; i< pole.length; i++) { // nikoli 0 if (Pole[i] > max) {

Konstruktory a destruktory

Objektov orientované programování. C++ Akademie SH. 7. Objektov orientované programování. Michal Kvasni ka. Za áte níci C++ 2.

Lineární spojový seznam (úvod do dynamických datových struktur)

for (int i = 0; i < sizeof(hodnoty) / sizeof(int); i++) { cout<<hodonoty[i]<< endl; } cin.get(); return 0; }

Programování v C++ 2, 8. cvičení

2) Napište algoritmus pro vložení položky na konec dvousměrného seznamu. 3) Napište algoritmus pro vyhledání položky v binárním stromu.

ALG 09. Radix sort (přihrádkové řazení) Counting sort. Přehled asymptotických rychlostí jednotlivých řazení. Ilustrační experiment řazení

Zápis programu v jazyce C#

Pole a kolekce. v C#, Javě a C++

Vyhledávání. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava. Prezentace ke dni 12.

Dynamické datové struktury III.

IB111 Úvod do programování skrze Python

Datové struktury. alg12 1

Programování v C++ 3, 3. cvičení

<surface name="pozadi" file="obrazky/pozadi/pozadi.png"/> ****************************************************************************

PB161 Programování v jazyce C++ Přednáška 8

Časová a prostorová složitost algoritmů

Dynamické datové typy a struktury

Programování v C++ 1, 1. cvičení

Pole, množina, tabulka

Obsah. Předmluva 13 Zpětná vazba od čtenářů 14 Zdrojové kódy ke knize 15 Errata 15

Programovanie

Datové struktury 2: Rozptylovací tabulky

Cvičení z programování v C++ ZS 2016/2017 Přemysl Čech

Algoritmy a datové struktury

PREPROCESOR POKRAČOVÁNÍ

C++ Akademie SH. 2. Prom nné, podmínky, cykly, funkce, rekurze, operátory. Michal Kvasni ka. 20. b ezna Za áte níci C++

PB přednáška (23. listopadu 2015)

ALG 14. Vícedimenzionální data. Řazení vícedimenzionálních dat. Experimentální porovnání řadících algoritmů na vícedimenzionálních datech

TGH07 - Chytré stromové datové struktury

Datové struktury 1: Základní datové struktury

PB161 Programování v jazyce C++ Přednáška 4

Jazyk C# (seminář 6)

Programování v C++ 2, 7. cvičení

Maturitní otázky z předmětu PROGRAMOVÁNÍ

Řetězce. Karel Richta a kol. katedra počítačů FEL ČVUT v Praze. Karel Richta, Martin Hořeňovský, Aleš Hrabalík, 2016

IB015 Neimperativní programování. Seznamy, Typy a Rekurze. Jiří Barnat Libor Škarvada

IAJCE Přednáška č. 8. double tprumer = (t1 + t2 + t3 + t4 + t5 + t6 + t7) / 7; Console.Write("\nPrumerna teplota je {0}", tprumer);

Lineární datové struktury

Mělká a hluboká kopie

Stromy, haldy, prioritní fronty

Definice uživatelského typu. Uživatelem definované typy. Součinové datové typy. Součtové datové typy. FLP - Uživatelem definované typy

Transkript:

PB161 Programování v jazyce C++ Přednáška 6 Kontejnery Iterátory Algoritmy Nikola Beneš 26. října 2015 PB161 přednáška 6: kontejnery, iterátory, algoritmy 26. října 2015 1 / 37

Standardní knihovna C++ Několik částí řetězce I/O proudy funkce ze standardní knihovny jazyka C (<cstdlib> apod.) dnes: kontejnery, iterátory, algoritmy a mnohé další Generické programování syntax container<object_type> Jmenný prostor std PB161 přednáška 6: kontejnery, iterátory, algoritmy 26. října 2015 2 / 37

Dnešní plán Kontejnery Iterátory generické objekty, které mohou obsahovat jiné objekty inteligentní ukazatele, pomocí kterých umíme kontejnery procházet Algoritmy generické operace nad kontejnery nebo jejich částmi využívají iterátory PB161 přednáška 6: kontejnery, iterátory, algoritmy 26. října 2015 3 / 37

Kontejnery & iterátory PB161 přednáška 6: kontejnery, iterátory, algoritmy 26. října 2015 4 / 37

Motivace složitější datové struktury různé druhy operací není jedna idální datová struktura uspořádání datové struktury je často nezávislé na konkrétním typu dat základní operace jsou shodné proto: generické kontejnery PB161 přednáška 6: kontejnery, iterátory, algoritmy 26. října 2015 5 / 37

Typy kontejnerů Sekvenční array (C++11) klasické pole vector dynamické pole, může se zvětšovat deque obousměrná fronta, rychlé přidávání/odebírání prvků forward_list (C++11), list zřetězený seznam Asociativní set uspořádaná množina map asociativní pole (slovník), uspořádané dle klíče multiset, multimap umožňují opakování klíčů unordered_set, unordered_map, unordered_multiset, unordered_multimap neuspořádané verze (hash tabulky), C++11 Adaptéry stack (zásobník), queue (fronta), priority_queue (prioritní fronta) PB161 přednáška 6: kontejnery, iterátory, algoritmy 26. října 2015 6 / 37

Související datové struktury Dvojice a ntice Řetězce pair drží dva objekty různých (nebo stejných) typů tuple (C++11) drží fixní počet objektů různých (nebo stejných) typů string fungují podobně jako kontejnery PB161 přednáška 6: kontejnery, iterátory, algoritmy 26. října 2015 7 / 37

Dvojice <utility> Šablonová třída pair pair<int, char> p1; p1.first = 17; p1.second = 'a'; pair<int, char> p2(p1); pair<int, float> p3(42, 3.14); p3 = p1; pair<string, int> psi; psi = make_pair("james Bond", 7); // je totéž jako psi = std::pair<const char *, int>("james Bond", 7); PB161 přednáška 6: kontejnery, iterátory, algoritmy 26. října 2015 8 / 37

Dynamické pole <vector> Šablonová třída vector pole, které se umí zvětšovat souvislý úsek paměti rychlost přístupu jako pole rychlé přidávání na konec alokace větší paměti + překopírování konstantní amortizovaná složitost podporuje i jiné operace vhodný pro mnohá použití PB161 přednáška 6: kontejnery, iterátory, algoritmy 26. října 2015 9 / 37

Dynamické pole (pokr.) <vector> Syntaxe: vector<typ> vector<int> vec; vec.push_back(17); vec.push_back(21); vec.push_back(0); for (int i = 0; i < vec.size(); ++i) { cout << vec[i] << endl; } cout << vec[9] << endl; // nehlídaný přístup cout << vec.at(9) << endl; // hlídaný přístup, vyhodí výjimku vec.pop_back(); if (vec.empty()) { /*... */ } PB161 přednáška 6: kontejnery, iterátory, algoritmy 26. října 2015 10 / 37

Dynamické pole (pokr.) <vector> at() je pomalejší než operátor [] nepoužívejte, když kontrola mezí nedává smysl! for (int i = 0; i < vec.size(); ++i) { cout << vec.at(i) << endl; // zbytečné! } [ukázka] rezervování kapacity, zvětšování vektoru vektory lze kopírovat PB161 přednáška 6: kontejnery, iterátory, algoritmy 26. října 2015 11 / 37

Iterátory základní myšlenka: inteligentní ukazatele různé druhy podle kontejneru sekvenční procházení různé další operace různé metody kontejnerů používají iterátory minimálně begin() a end() begin() vrací iterátor na začátek kontejneru end() vrací iterátor za konec kontejneru PB161 přednáška 6: kontejnery, iterátory, algoritmy 26. října 2015 12 / 37

Iterátory pro vector Syntax: jako ukazatele do pole vector<typ>::iterator (pro čtení i zápis) vector<typ>::const_iterator (jen pro čtení) vector<int> vec; // naplnění vektoru nějakými daty vec.push_back(10); vec.push_back(20); vector<int>::iterator vecit = vec.begin(); cout << *vecit << endl; ++vecit; // posunutí na další prvek cout << *vecit << endl; // vypíše 20 --vecit; // posunutí na předchozí prvek PB161 přednáška 6: kontejnery, iterátory, algoritmy 26. října 2015 13 / 37

Iterátory pro vector (pokr.) Procházení vektoru for (vector<int>::iterator it = vec.begin(); it!= vec.end(); ++i) { cout << *it << endl; *it = 17; } // vec.end() ukazuje ZA poslední prvek vektoru Invalidace iterátorů v případě, že se vektor zvětší, přestávají iterátory být platné PB161 přednáška 6: kontejnery, iterátory, algoritmy 26. října 2015 14 / 37

Užitečné zkratky pro iterování v C++11 Automatická dedukce typu typový specifikátor auto používat opatrně hodí se pro iterátory for (auto it = vec.begin(); it!= vec.end(); ++i) { cout << *it << endl; } Nová syntax cyklů for range-based for for (int element : vec) { cout << element << endl; } funguje i pro klasická pole PB161 přednáška 6: kontejnery, iterátory, algoritmy 26. října 2015 15 / 37

Užitečné zkratky pro iterování v C++11 (pokr.) pokud chceme prvky kontejneru měnit, musíme brát prvek referencí for (int & element : vec) { cout << element << endl; element += 17; } jak to funguje? for (typ objekt : kontejner) {... } // znamená něco jako: (ve skutečnosti trochu složitější) for (auto it = kontejner.begin(); it!= kontejner.end(); ++it) { typ objekt = *it;... } PB161 přednáška 6: kontejnery, iterátory, algoritmy 26. října 2015 16 / 37

Uspořádaná množina <set> Šablonová třída set prvky se neopakují prvky se dají uspořádat typická implementace: stromy (často red-black trees) rychlé vkládání, mazání, vyhledávání iterátory vždy konstantní (neměnitelné) PB161 přednáška 6: kontejnery, iterátory, algoritmy 26. října 2015 17 / 37

Uspořádaná množina (pokr.) <set> set<int> s; s.insert(17); s.insert(25); s.insert(9); s.insert(-4); s.erase(17); s.erase(11); if (s.empty()) { /*... */ } cout << s.size() << endl; // vypíše 3 PB161 přednáška 6: kontejnery, iterátory, algoritmy 26. října 2015 18 / 37

Uspořádaná množina (pokr.) <set> Vyhledávání iterátor na prvek, pokud existuje end(), pokud ne set<int>::iterator it = s.find(17); if (it!= s.end()) { // množina obsahuje 17 // můžeme používat *it, ale jen ke čtení, ne k zápisu } else { // množina neobsahuje 17 } PB161 přednáška 6: kontejnery, iterátory, algoritmy 26. října 2015 19 / 37

Uspořádaná množina (pokr.) <set> Iterátory při vkládání/mazání for (auto it = s.begin(); it!= s.end(); ) { if ( *it % 2 == 1 ) { it = s.erase(it); } else { ++it; } } pair< set<int>::iterator, bool > result = s.insert(-4); if (result.second) { // vložení proběhlo } else { // prvek -4 už v množině byl } PB161 přednáška 6: kontejnery, iterátory, algoritmy 26. října 2015 20 / 37

Asociativní kontejner <map> Šablonová třída map asociativní pole, slovník mapování klíčů na hodnoty uspořádání podle klíčů klíče se nemohou opakovat funguje podobně jako set map<int, string> cppteachers; cppteachers.insert(make_pair(72525, "Nikola Benes")); cppteachers.insert(make_pair(374154, "Jiri Weiser")); cppteachers.erase(374154); cppteachers.erase(4085); // C++11 cppteachers.insert( {72525, "Nikola Benes"} ); PB161 přednáška 6: kontejnery, iterátory, algoritmy 26. října 2015 21 / 37

Asociativní kontejner (pokr.) <map> Vyhledávání iterátor na záznam, tj. dvojici (klíč, hodnota) klíč se nesmí modifikovat, hodnota ano map<int, string>::iterator it = cppteachers.find(72525); if (it!= cppteachers.end()) { // cppteachers obsahuje záznam s klíčem 72525 cout << it->first << ": " << it->second << endl; // vypíše 72525: Nikola Benes it->second += ", Ph.D."; // it->first nelze použít k zápisu } else { // cppteachers neobsahuje záznam s klíčem 72525 } PB161 přednáška 6: kontejnery, iterátory, algoritmy 26. října 2015 22 / 37

Asociativní kontejner (pokr.) <map> Operátor [] uvnitř operátoru [] je klíč pokud záznam neexistuje, automaticky se vytvoří použivejte opatrně (dávejte přednost spíš insert a find) map<string, int> namestouco; namestouco["nikola Benes"] = 72525; // přístup k neexistujícímu záznamu jej vytvoří if (namestouco["james Bond"] == 7) { /*... */ } map<string, int>::iterator it = namestouco.find("james Bond"); if (it!= namestouco.end()) { cout << it->second << endl; // vypíše 0 } PB161 přednáška 6: kontejnery, iterátory, algoritmy 26. října 2015 23 / 37

Algoritmy PB161 přednáška 6: kontejnery, iterátory, algoritmy 26. října 2015 24 / 37

Knihovna algoritmů <algorithm> různé užitečné algoritmy funkcionální styl programování v C++ využívá iterátorů jednotný způsob, jak zacházet s objekty uvnitř kontejnerů rozsah (range) dvojice iterátorů iterátor na první prvek rozsahu iterátor za poslední prvek rozsahu algoritmy fungují i s klasickými poli ukazatele fungují jako iterátory PB161 přednáška 6: kontejnery, iterátory, algoritmy 26. října 2015 25 / 37

Řazení Algoritmus sort int arr[8] = {27, 8, 6, 4, 5, 2, 3, 0}; sort(arr, arr + 8); // C++11 array<int,8> arr2 = {27, 8, 6, 4, 5, 2, 3, 0}; sort(arr2.begin(), arr2.end()); vector<int> vec; vec.push_back(9); vec.push_back(6); vec.push_back(17); vec.push_back(-3); sort(vec.begin(), vec.end()); PB161 přednáška 6: kontejnery, iterátory, algoritmy 26. října 2015 26 / 37

Řazení (pokr.) Porovnávání implicitně: operátor < můžeme dodat vlastní funkci bool pred(int x, int y) { return y < x; } sort(vec.begin(), vec.end(), pred); některé porovnávací funkční objekty už máme v knihovně algoritmů připravené sort(vec.begin(), vec.end(), greater<int>()); Poznámka: sort nemusí být stabilní, proto standardní knihovna obsahuje ještě algoritmus stable_sort PB161 přednáška 6: kontejnery, iterátory, algoritmy 26. října 2015 27 / 37

Kopírování Algoritmus copy zdrojový rozsah, cílový iterátor je třeba zajistit, aby v cílovém kontejneru bylo dost místa set<int> s; s.insert(15); s.insert(6); s.insert(-7); s.insert(20); vector<int> vec; vec.resize(7); // vec obsahuje {0, 0, 0, 0, 0, 0, 0} copy(s.begin(), s.end(), vec.begin() + 2); // vec nyní obsahuje {0, 0, -7, 6, 15, 20, 0} PB161 přednáška 6: kontejnery, iterátory, algoritmy 26. října 2015 28 / 37

Kopírování (pokr.) Algoritmus copy_if (C++11) kopírují se jen objekty splňující daný predikát funkce vracející bool bool isodd(int num) { return (num % 2)!= 0; } array<int, 5> arr = {1, 2, 3, 4, 5}; // s je množina { -7, 6, 15, 20 } copy_if(s.begin(), s.end(), arr.begin(), isodd); // arr nyní obsahuje {-7, 15, 3, 4, 5}; PB161 přednáška 6: kontejnery, iterátory, algoritmy 26. října 2015 29 / 37

Transformace Algoritmus transform kopírování s modifikací dvě varianty první varianta: unární funkce jako parametr funkcionální prvek C++: podobné map v Haskellu // s je množina { -7, 6, 15, 20 } vector<double> vec; vec.resize(7); // vec obsahuje sedmkrát 0.0 double half(int num) { result num / 2.0; } transform(s.begin(), s.end(), vec.begin() + 1, half); // vec nyní obsahuje 0.0, -3.5, 3.0, 7.5, 10.0 PB161 přednáška 6: kontejnery, iterátory, algoritmy 26. října 2015 30 / 37

Transformace druhá varianta: dva zdroje, binární funkce podobné zipwith v Haskellu vector<int> vec; vec.resize(7); vec[3] = 17; array<char, 7> arr = {'a', 'b', 'c', 'd', 'e', 'f', 'g'}; string combine(int num, char c) { return to_string(num) + ":" + c; } array<string, 7> strarr; transform(vec.begin(), vec.end(), arr.begin(), strarr.begin(), combine); // strarr nyní obsahuje "0:a", "0:b", "0:c", "17:d", // "0:e", "0:f", "0:g" PB161 přednáška 6: kontejnery, iterátory, algoritmy 26. října 2015 31 / 37

Akumulace Algoritmus accumulate sečte všechny objekty v zadaném rozsahu pomocí operátoru + umožňuje dodat vlastní funkci počáteční hodnotu akumulace probíhá zleva podobné foldl v Haskellu array<int, 6> arr = {1, 7, 8, 3, 2, 3}; int s = accumulate(arr.begin(), arr.end(), 100); // s je 124 PB161 přednáška 6: kontejnery, iterátory, algoritmy 26. října 2015 32 / 37

Akumulace (pokr.) string producer(const string & s, int num) { return s.empty()? to_string(num) : s + ", " + to_string(num); } string str = accumulate(arr.begin(), arr.end(), string(), producer); // str nyní obsahuje řetězec "1, 7, 8, 3, 2, 3" PB161 přednáška 6: kontejnery, iterátory, algoritmy 26. října 2015 33 / 37

Funkční objekty Funkční objekt objekt třídy s operátorem () možno volat jako funkce výhoda: mohou držet vnitřní stav class LessThan { int threshold; public: LessThan(int t) : threshold(t) {} bool operator()(int num) { return num < threshold; } }; array<int, 7> arr = {5, 7, 8, 0, 2, -3, 99}; cout << count_if(arr.begin(), arr.end(), LessThan(7)) << endl; PB161 přednáška 6: kontejnery, iterátory, algoritmy 26. října 2015 34 / 37

Funkční objekty (pokr.) class Tagger { int id; public: Tagger() : id(0) {} string operator()(int num) { str = to_string(id) + ": " + to_string(num); ++id; return str; } int getid() const { return id; } }; vector<string> vec; vec.resize(7); Tagger tagger; transform(arr.begin(), arr.end(), vec.begin(), tagger); PB161 přednáška 6: kontejnery, iterátory, algoritmy 26. října 2015 35 / 37

Funkční objekty (pokr.) předdefinované funkční objekty <functional> obalují běžné operátory vector<int> intvec; intvec.resize(7); transform(arr.begin(), arr.end(), vec.begin(), negate<int>()); // co bude v intvec nyní? PB161 přednáška 6: kontejnery, iterátory, algoritmy 26. října 2015 36 / 37

Shrnutí Kontejnery Iterátory Algoritmy Používejte dokumentaci: http://cppreference.com http://cplusplus.com/reference PB161 přednáška 6: kontejnery, iterátory, algoritmy 26. října 2015 37 / 37