Az előadás letöltése folymat van. Kérjük, várjon

Az előadás letöltése folymat van. Kérjük, várjon

Haladó C++ Programozás SzJ/IV. Az STL sablonkönyvtár Iterátorok, műveletek intervallumokkal 2013. október Előadó: Szigeti János

Hasonló előadás


Az előadások a következő témára: "Haladó C++ Programozás SzJ/IV. Az STL sablonkönyvtár Iterátorok, műveletek intervallumokkal 2013. október Előadó: Szigeti János"— Előadás másolata:

1 Haladó C++ Programozás SzJ/IV. Az STL sablonkönyvtár Iterátorok, műveletek intervallumokkal október Előadó: Szigeti János

2 STL 2 Témáink copy függvény iterátorok  iterator tags  speciális iterátorok insert_iterator output_iterator input_iterator algoritmusok  halmazműveletek  bejárás, keresés, lecserélés

3 STL 3 copy fv. template OutputIterator copy(InputIterator first, InputIterator last, OutputIterator result); [first, last) szakaszból [result, result + (last - first)) -ba másolja az elemeket *result = *first, *(result + 1) = *(first + 1),..., *(result + n) = *(first + n) Pl. copy_demo.cc pontosabban:  a bemeneti intervallum elejétől kezdve x=*first++; művelettel olvassa az adatokat;  a kimenetre *result++=x; művelettel ír;  mindaddig, amíg first==last nem lesz. Így nemcsak kész konténerekre, hanem elvont intervallumokra is használható (ld. [i|o]stream_iterator, insert_iterator)

4 STL 4 Iterator tags Az iterátorral kapcsolatos információk kinyerésére pl.: distance_type, value_type Használata: segédfüggvény sablonokban  gyakori példa: algoritmus definiálása intervallumra (iterátor pár) az intervallum elemeinek megfogása iter_traits.cc

5 STL 5 insert_iterator Típusa: kimeneti iterátor  csak írhatunk bele  eredményintervallum elejét definiálhatjuk vele (pl. copy algoritmusban) Konténerekre definiálható  tipizálás konténerrel typedef insert_iterator > IntVII;  inicializálás (konstruktorban) konténerrel és iterátorral vector i0_v; IntVII i0_vii(i0_v,i0_v.begin());  makró a tároló ::insert(it,dat) függvényére speciálisan ha az iterátor begin() vagy end() lenne, és a konténernek létezik a push_*() függvénye:  front_insert_iterator -> push_front()  back_insert_iterator -> push_back() Pl. insert_vector.cc, insert_iterator_demo.cc egyszerűbb megadási mód:  inserter(Container,iterator); inserter_demo.cc  front_inserter(Container); back_inserter(Container); Mi a különbség az alábbiak között?  copy(a.begin();a.end(),b.begin());  copy(a.begin();a.end(),inserter(b,b.begin()));

6 STL 6 ostream_iterator Szintén kimeneti iterátor kétféle konstruktor: ostream_iterator(ostream& s)  s << t ostream_iterator(ostream& s, const char* delim)  s << t << delim A definiált operátorok ( ++,*,= ) felüldefiniálásával lehet trükközni! Pl. ostreamiter_demo.cc és MyOstreamIterator.h

7 STL 7 istream_iterator Bemeneti iterátor  csak olvasunk alóla: dat=*it++; kétféle konstruktor:  istream_iterator(istream& s) ez a szokványos  istream_iterator() ez pedig utolsó utáni iterátorral egyezik meg ( operator== : true) - for ciklus lezárásához kell! Pl. istreamiter_demo.cc és halmaz4_demo.cc

8 STL 8 Algoritmusok csoportosítása Belső vagy külső fv.  belső fv. a struktúrára optimalizált Rendezett bemenettel dolgozik-e  igen: unique(), merge(), set_union() stb. Tartalmon módosít-e  nem: find(), count(), search(), equal() stb.  igen: sort(), unique(), merge(), copy(), replace() stb.  igen: külön kimeneti intervallummal dolgozik-e Hány bemeneti intervallummal dolgozik  1-gyel  2-vel Kimenete  iterator intervallum-vég pozíció  érték (pl. aggregátum) vectorlist_demo.cc

9 STL 9 Algoritmusok – belső v. külső fv. vectorlistsetmap sizebbbb emptybbbb findkkbb countkkbb mergekbkk uniquekb-- sortkb-- removekb-- reversekb-- erase! automatikusan rendezve automatikusan egyedi Külső fv. előnyei:  különböző konténertípusokra működik. Pl. merge list +set  intervallum rugalmasan definiálható hátrányok:  nem használhatóak ki a konténer struktúrája által adott előnyei  intervallum mérete nem módosítható. Pl. remove, unique

10 STL 10 lásd less Halmazműveletek (1) rendezett adatsorokon végezhetőek  set, map alapból rendezett  vector, list: előbb sort(), aztán hajrá megadási szintaxis:  template OutputIterator set_op(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result); vagy:  template OutputIterator set_op(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, StrictWeakOrdering comp);

11 STL 11 Halmazműveletek (2) unió/metszet: azonos elemek többször ( max(m,n) ill. min(m,n) ) is megjelennek a kimeneten Pl. halmaz1_demo.cc, halmaz2_demo.cc különbség: azonos elemek max(m-n,0) - szor jelennek meg a kimeneten Pl. halmaz3_demo.cc szimmetrikus különbség: azonos elemek abs(m-n) -szer jelennek meg a kimeneten Pl. halmaz4_demo.cc

12 STL 12 Algoritmusok közelebbről Értéket nem változtató algoritmusok  for_each  find_if  search  equal Értéket módosító algoritmusok  copy  replace  replace_if

13 STL 13 for_each sablon Az intervallum összes tagját egyenként argumentumul véve végrehajt egy függvényt template UnaryFunction for_each(InputIterator first, InputIterator last, UnaryFunction f); definiálandó: void f::operator() (T x);  x típusa T vagy const T&, de nem T& - nem módosítható  void (*function)(const T&) típusú fv.ptr. is megadható példa: foreach1_demo.cc, foreach2_demo.cc, foreach3_demo.cc InputIterator, vagyis csak olvasásra szánt

14 STL 14 Házi feladat Melyik operátora hányszor hívódott meg az OutputIteratornak?  Egészítsd ki a hf07_oiCnt.cc-ben megadott ostream_iterator -t, hogy az számolja a függvényhívásokat  Használd a copy fv.-ben ezt a saját OstreamIteratorCnt iterátort a mostani ostream_iterator helyett  A copy lefutása után írd ki, mi hányszor hívódott meg (külső objektum elérése ld. foreach2_demo.cc) Szorgalmi  módosítsd az OstreamIteratorCnt -t sablonná, hogy ne csak int -ekre működjön  az egyes függvények hívásának sorrendjét is jegyezze meg (counter helyett history változó)

15 STL 15 find_if függvény find()-dal ellentétben nem értékre keres, hanem az első olyan objektumra, melyre igaz egy állítás (Predicate). template InputIterator find_if(InputIterator first, InputIterator last, Predicate pred); Az állítás típusa unary_function példa: findif_demo.cc argreturn

16 STL 16 Search függvény intervallumot keres egy másik intervallumban template ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate binary_pred); példa: search1_demo.cc, search2_demo.cc Megj.: ForwardIterator vs. InputIterator: a search a megadott intervallumok elemeit (op*-gal) többször is ki akarja olvasni. Az InputIterator nem garantálja, hogy az iterátor alatt op*-gal elért elem mindig ugyanaz lesz – lásd: istream_iterator !

17 STL 17 equal függvény megnézi, hogy a két intervallum megegyezik- e  sorrend is számít  egyezőség vizsgálata predicate alapján történhet template bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate binary_pred);

18 STL 18 replace függvény az intervallum összes old_value -val egyező elemét new_value -ra cseréli template void replace(ForwardIterator first, ForwardIterator last, const T& old_value,const T& new_value) párja: replace_if  old_value helyett feltétel adható meg példa: replace_demo.cc, replace_if_demo.cc

19 STL 19 replace_copy A replace függvény sem képes const T& típusú elemeket (pl. const T& set ::iterator::operator*() ) felülírni Lehetséges megoldás:  while ciklusban: find/find_if, erase, insert veszély: iterálás közben erase/insert (ld. később)  új tároló létrehozása, s bele már a módosított adatok töltése template OutputIterator replace_copy(InputIterator first, InputIterator last, OutputIterator result, const T& old_value, const T& new_value); Pl: replace_copy_demo.cc

20 STL 20 transform Mi van akkor, ha a régi értéktől függő új értékkel akarjuk megoldani a replace() -t?  if (pred(old_val)==true) new_val=func(old_val)  Ez ekvivalens azzal, hogy new_val=func(old_val) és func(val) {if (pred(val)==true) return val; /eredeti func body/ } különbség: a replace az irreleváns elemeket békén hagyja, a transform őket is "birizgálja"  teendő: az irreleváns adatok miatti járulékos feladatok minimalizálása. (Pl. pointer szerinti adatátadás)

21 STL 21 transform Általánosan: template OutputIterator transform(InputIterator first, InputIterator last, OutputIterator result, UnaryFunction op); vagy kéttagú műveletekre: template OutputIterator transform(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, OutputIterator result, BinaryFunction binary_op); Pl.: transform_demo.cc


Letölteni ppt "Haladó C++ Programozás SzJ/IV. Az STL sablonkönyvtár Iterátorok, műveletek intervallumokkal 2013. október Előadó: Szigeti János"

Hasonló előadás


Google Hirdetések