220 likes | 463 Views
Užitočné veci v knižniciach C++ zoznamy, trieda vector , dynamická alokácia pamäte, triedenie, matica ako vector. Zoznam ( vector ). Funkcie pre prácu so zoznamom vector sú v knižnici <vector>
E N D
Užitočné veci v knižniciach C++zoznamy, trieda vector, dynamická alokácia pamäte,triedenie, matica ako vector
Zoznam (vector) • Funkcie pre prácu so zoznamom vector sú v knižnici <vector> • Často potrebujeme pracovať s dlhými zoznamami (napríklad s vektormi), ktorých dĺžku v čase kompilácie nepoznáme • Rezervovať zbytočne veľký priestor, ak ho nepotrebujeme, je kontraproduktívne • Napríklad rezervovať „pre istotu“ double x[1000000], ak obvykle potrebujeme 100 prvkov, je nevhodné
Zoznam (vector) - vytvorenie • Elegantné riešenie predstavuje trieda vector • Je to zoznam (napríklad čísel), ktorý narastá automaticky podľa potreby • Deklarácia zoznamu čísel float: vector <float> v; Meno premennej (zoznamu) objekt triedy vector Ukladať sa budú čísla typu float
Zoznam (vector) - vytvorenie • Iné možnosti deklarácie: vector <float> v(100); vector <float> v(100,2.1); Zarezervuje sa úvodný priestor pre 100 prvkov, všetky majú hodnotu 0 Zarezervuje sa úvodný priestor pre 100 prvkov, všetky majú hodnotu 2.1
Zoznam (vector) - vytvorenie • Iné možnosti deklarácie: vector <float> v2(v); • „Doinicializovanie“ hodnôt: v.resize(n,2.1); v = meno jestvujúceho zoznamu, urobí sa jeho kópia Ak nová veľkosť je menšia, vymažú sa zvyšné prvky. Ak nová veľkosť je väčšia, doplnia sa nové prvky s uvedenou hodnotou Ak hodnota nie je uvedená, nové prvky majú hodnotu 0.
Zoznam (vector) - pridávanie • Pridať prvok do zoznamu na jeho koniec: v.push_back(1.8); • Zistenie aktuálneho počtu prvkov: v.size(); Pridať prvok na koniec zoznamu Hodnota pridaneho prvku Ak nová veľkosť je menšia, vymažú sa zvyšné prvky. Ak nová veľkosť je väčšia, doplnia sa nové prvky s uvedenou hodnotou Ak hodnota nie je uvedená, nové prvky majú hodnotu 0.
Zoznam (vector) – dĺžka, hodnota • Zoznam môže mať obrovskú dĺžku – také veľké celé číslo sa nemusí vmestiť do int alebo long. • Špeciálny celočíselný dátový typ pre veľkosti: size_t i; • Od slov (size type), dokáže obsiahnuť najväčšie celé číslo, aké dokáže spracovať architektúra počítača. • 32-bit systém = 232 – 1 = 4 byte • 64-bit systém = 264 – 1 = 8 byte • 128-bit systém = 2128 – 1 = 16 byte • Prístup k prvkom zoznamu • v[0], v[v.size()-1], v[i]
Zoznam (vector) - pridávanie • Príklad: Vloženie vopred neznámeho počtu čísel z klávesnice, vpočet aritmetického priemeru. vector<float> v; floatcislo,priemer=0; cout<< "Zadaj cisla, pre ukoncenievloz‘k’<< endl; while(cin>>cislo) //kym sa darinacitatcislo { v.push_back(cislo); } for(size_ti=0; i<v.size();i++) priemer+=v[i]; priemer /= v.size(); cout<< "Pocetcisel= " << v.size() << endl; cout<< „Priemer = " << priemer << endl;
Zoznam (vector) - operácie • Prístup k prvkom zoznamu s kontrolou hraníc: v.at(15); • Pokus o prístup k neexistujúcemu prvku zoznamu vyvolá chybu (samozrejme až počas behu programu) • Hodnota prvého prvku sa dá získať (okrem prístupu cez jeho index = 0) aj: v.front() • Hodnota posledného prvku sa dá získať (okrem prístupu cez jeho index = v.size()-1) aj: v.back()
Zoznam (vector) - operácie • Prístup k prvkom vo vnútri zoznamu (okrem prístupu cez index) – pomocou adresy prvku, t.j. cez tzv. iterátor(technický termín pre prácu so zoznamami) • Je to v podstate adresa v pamäti, kde sa nachádza daný prvok, ale pri zväčšení iterátora o 1sa iterátor v skutočnosti zväčší o toľko bajtov, koľko zaberá jeden prvok zoznamu • Automaticky pripravené iterátory: • v.begin() – ukazuje na prvý prvok zoznamu • v.end() – ukazuje na posledný prvok zoznamu
Zoznam (vector) - operácie • Dátový typ na odkladanie hodnoty iterátora(závisí na type uložených dát), napr.: vector<float> v; vector<float>::iteratorit=v.begin(); Iterátor bude ukazovať na zoznam prvkov typu float Ide o premennú typu iterator Meno premennej Adresa začiiatku zoznamu
Zoznam (vector) - vkladanie • Funkcia insert() : v.insert(iterator kam, hodnota); • Príklad – vloženie čísla 2.1 medzi 4. a 5.pozíciu v.insert(v.begin()+4, 2.1); • Príklad – vloženie 6 núl medzi 2.a 3.pozíciu od konca v.insert(v.end()-3, 6, 0);
Zoznam (vector) - mazanie • Funkcia erase() : • Príklad – vymazanie 1. prvku: v.erase(v.begin()); • Príklad – vymazanie prvých 5 prvkov v.erase(v.begin(), v.begin()+4); • Funkcia clear() – vymaže celý obsah zoznamu: v.clear(); • Po vyvolaní funkcie clear() zoznam neobsahuje žiaden prvok
Zoznam (vector) - triedenie • Funkcia sort, spolu so súvisiacimi funkciami, sa nachádza v knižnici <algorithm> vector <float> v; ... sort(v.begin(),v.end()); Koniec oblasti pre utriedenie Začiatok oblasti pre utriedenie Utriedi zoznam od najmenšieho prvku po najväčší
Zoznam (vector) - triedenie • Funkcia reverse, otočí poradie prvkov na opačné (veľmi jednoduché a rýchle) vector <float> v; ... sort(v.begin(),v.end()); reverse(v.begin(),v.end()); Najprv sa zoznam utriedi od najmenšieho prvku po najväčší, potom sa otočí poradie prvkov, získame zoznam usporiadaný od najväčšieho po najmenší
Zoznam (vector) - triedenie • Triediť môžeme aj podľa ľubovoľného iného kritéria, napríklad podľa veľkosti desatinnej časti, ... • Možno si zadefinovať ľubovoľnú funkciu pre porovnávanie, napr. vector <float> v; ... bool Porovnaj(float a, float b) { return a<b; } Funkcia má vrátiť true, ak prvky a,b sú v správnom poradí. V príklade dôjde k utriedeniu od najmenšieho prvku po najväčší
Zoznam (vector) - triedenie • Použitie: boolPorovnaj(float, float); intmain() { vector <float> v; ... sort(v.begin(), v.end(), Porovnaj); ... } boolPorovnaj(float a, float b) { return a<b; }
Zoznam (vector) - triedenie • Iné triediace algoritmy • sort () - používa rýchly triediaci algoritmus (quick sort), ale nezachováva poradie prvkov, ktorých hodnoty sú rovnaké • stable_sort() – iba o málo pomalší algoritmus zachovávajúci poradie ekvivalentných prvkov • sort_heap() – za niektorých okolností (množstvo údajov, predtriedenie) môže byť rýchlejší, než sort() • Použitie a argumenty – ako sort() • Funkcia sort() vie triediť aj iné zoznamy, napríklad pole float x[100], namiesto iterátorov treba do funkcie poslať referenciu (adresu) začiatku poľa (prvku x[0] a konca poľa (ešte neexistujúceho prvku x[100]): sort(&x[0], &x[100]);
Zoznam (vector) – max, min, search • Maximálna a minimálna hodnota • min_element(v.begin(),v.end()) – vráti iterátor na najmenší prvok zo zoznamu • max_element(v.begin(),v.end()) – vráti iterátor na najväčší prvok zo zoznamu • Vyhľadávanie podzoznamu v zozname • search(v1,v2) – vráti iterátor na prvý výskyt podzoznamu v2 v zozname v1
vector – použitie ako matice • Zoznam má veľa dobrých vlastností, najmä dynamickú alokáciu počas behu programu • Veľmi cenná vec u matíc (obrovské množstvá dát) • Matica je beztak v pamäti uložená lineárne (riadok po riadku), možno využiť triedu vector • Príklad: potrebujeme maticu float 100 x 200 (100 riadkov po 200 stĺpcoch) vector <float> m(100*200); • Jediná komplikácia – prístup k prvku mij: m[i][j] m[i*200+j]
vector – referencia • Samozrejme, funkcii môžeme odovzdať aj referenciu na zoznam: vector <float> &v; • Ďalšia výhoda – nemusíme posielať dĺžku zoznamu (ako sme museli pri referenciách na vektory a matice), dĺžku si vieme vo funkcii ľahko zistiť: v.size()