Programozá alapjai II. (13. ea) C++ vizalépée (backtrack) algoritmuok táblá játékok, özefoglalá Szeberényi Imre BME IIT <zebi@iit.bme.hu> Nyolc királynő probléma Helyezzünk el nyolc királynőt úgy egy akktáblán, hogy azok ne üék egymát! Egy megoldát kereünk nem kereük az öze lehetége elhelyezét. M Ű E G Y E T E M 1 7 8 2 C++ programozái nyelv BME-IIT Sz.I. 2016.05.17. - 1-2016.05.17. - 2 - Probálgatá Egy ozlopban cak egy királynő lehet, ezért ozloponként próbálgatunk. Vizalépé (back track) A 24. lépében vizalépünk, é levezük a korábban már elhelyezett királynőt. 2016.05.17. - 3-2016.05.17. - 4 - Vizalépé é újból próba A 36. lépében imét viza kell lépni. A 60. lépé imét kudarcba fullad. Vizalépé é újból próba Egy lehetége megoldát a 876. lépében kapunk. 2016.05.17. - 5-2016.05.17. - 6 -
Hogyan modellezhető Oko tábla, buta királynő A akktábla imeri a zabályokat é nyilvántartja a királynők helyzetét. A királynő lényegében nem cinál emmit. Oko királynő, buta tábla A királynő imeri a zabályokat é nyilvántartja a aját pozícióját. A akktábla nem tud emmit. Okokodó tábla, oko királynő Oko tábla metóduai: Szabad adott pozícióra lehet-e lépni Lefoglal adott pozíciót lefoglalja Felzabadít adott pozíciót felzabadítja Rajzol kirajzolja a pillanatnyi állát Probal elhelyezi a királynőket 2016.05.17. - 7-2016.05.17. - 8 - Metódu pec. - Szabad bool Szabad(int or, int ozlop); megvizgálja, hogy az adott helyre lehet-e királynőt tenni. bemenet: or or (1..8) ozlop ozlop (1..8) kimenet: true a pozíció zabad fale ütében van a királynő Metódu pec. - Lefoglal void Lefoglal(int or, int ozlop); Lefoglalja az adott pozíciót. bemenet: or or (1..8) ozlop ozlop (1..8) 2016.05.17. - 9-2016.05.17. - 10 - Metódu pec. - Felzabadit void Felzabadit(int or, int ozlop); Felzabadítja az adott pozíciót. bemenet: or or (1..8) ozlop ozlop (1..8) Metódu pec. - Rajzol void Rajzol(int or, int ozlop); Kirajzolja a táblát. Az aktuáli or, ozlop pozícióba jelet tez bemenet: or or (1..8) ozlop ozlop (1..8) 2016.05.17. - 11-2016.05.17. - 12 -
Metódu pec. - Probal bool Probal(int ozlop); A paraméterként kapott ozlopba é az azt követő ozlopokba megpróbálja elhelyezni a királynőket bemenet: ozlop orzáma (1..8) kimenet: true - ha ikrült a 8. ozlopba i. fale - ha nem ikerült 2016.05.17. - 13 - Implementáció - Probal bool Probal(int ozlop) { int iker = 0, or = 1; do { if (Szabad(or, ozlop)) { Lefoglal(or, ozlop) if (ozlop < 8) iker = Probal(ozlop+1); ele iker = 1; if (!iker) Felzabadit(or, ozlop); or++; while (!iker && or <= 8); return(iker); következő ozlopba nem ikerült, vizalép 2016.05.17. - 14 - Adatzerkezet (mit kell tárolni) Átlók tároláa Adott orban van-e királynő 8 or: vektor 1..8 indexzel Adott átlóban van-e királynő főátlóval párhuzamo átlók jellemzője, hogy a or-ozlop = álladó (-7..7-ig 15 db átló) mellékátlóval párhuzamo átlók jellemzője, hogy a or+ozlop = álladó (2..16-ig 15 db átló) 2016.05.17. - 15 - or - ozlop = állandó 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 or + ozlop = állandó 2016.05.17. - 16 - Tabla oztály megvalóítáa cla Tabla { bool or[8]; bool f_atlo[15]; bool m_atlo[15]; int tab[8]; int probalkoza; // orok foglaltága // főátlók (-o) // mellékátlók (+o) // kiírához kell // kiírához kell bool& Sor(int i) { return or[i-1]; bool& Fo(int, int o) { return f_atlo[-o+7]; bool& Mellek(int, int o) { return m_atlo[+o-2]; int& Tab(int ) { return tab[-1]; Tabla oztály megvalóítáa /2 bool Szabad(int, int o) { return Sor() && Fo(, o) && Mellek(, o); void Lefoglal(int, int o) { Sor() = Fo(, o) = Mellek(, o) = fale; Tab() = o; void Felzabadit(int, int o) { Sor() = Fo(, o) = Mellek(, o) = true; Tab() = 0; 2016.05.17. - 17-2016.05.17. - 18 -
Tabla oztály megvalóítáa /3 Tabla(); bool Probal(int ozlop); void Rajzol(int or, int ozlop); ; Tabla::Tabla() { probalkoza = 0; for (int i = 0; i < 15; i++) { f_atlo[i] = m_atlo[i] = true; if (i < 8) { or[i] = true; tab[i] = 0; 2016.05.17. - 19 - Tabla oztály megvalóítáa /4 bool Tabla::Probal(int ozlop) { int or = 1; bool iker = fale; do { Rajzol(or, ozlop); if (Szabad(or, ozlop)) { Lefoglal(or, ozlop); if (ozlop < 8) iker = Probal(ozlop+1); ele iker = true; if (!iker) Felzabadit(or, ozlop); or++; while (!iker && or <= 8); return iker; 2016.05.17. - 20 - Működé megfigyelée A minden próbálkozát zámolunk: kell egy zámláló: probalkoza Minden próbálkozát kirajzolunk: * a már elhelyezett királynők helyére a próba helyére kell tárolni a táblát: tabla változó Implementáció - kiir void Tabla::Rajzol(int or, int ozlop) { cout.width(3); cout << ++probalkoza << ".\n"; for (int i = 1; i <= 8; i++) { cout.width(5); cout << 9-i << ' '; for (int j = 1; j <= 8; j++) { if (i == or && j == ozlop) cout << " "; ele if (Tab(i) == j) cout << "* "; ele cout << " "; cout << endl; cout << " A B C D E F G H\n\n"; 2016.05.17. - 21-2016.05.17. - 22 - Főprogram Eredmények int main() { Tabla t; if (t.probal(1)) { t.rajzol(8, 0); cout << "Siker"; ele cout << "Baj van"; // véglege áll. kirajzoláa 60. 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 A B C D E F G H 638. 8 * 7 6 5 4 3 2 1 A B C D E F G H 2016.05.17. - 23-2016.05.17. - 24 -
Eredmények /2 Oko királynő 876. 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 * A B C D E F G H Kiralyno *babu = NULL; for (int i = 1; i <= 8; i++) { babu = new Kiralyno(i, babu); babu->helyezkedj(); bool Kiralyno::Helyezkedj() { while (zomzed!= NULL && zomzed->uteben(or, ozlop)) if (!Lep()) return fale; return true; 2016.05.17. - 25-2016.05.17. - 26 - Oko királynő metóduai: Uteben Ellenőrzi, hogy az adott pozíció ütében áll-e. Lep Előre lép az adott ozlopban, ha nem tud, akkor az ozlop elejére áll é a tőle balra levőt lépteti. Helyezkedj Jó helyet kere magának. Kiír kiírja a pozícióját. Metódu pec. - Uteben bool Uteben(int or, int ozlop); megvizgálja, hogy az adott pozíció ütében álle a aját pozíciójával, ha nem, akkor azono paraméterekkel meghívja a zomzéd Uteben() tagfüggvényét. bemenet: or or (1..8) ozlop ozlop (1..8) kimenet: true a pozíció ütében áll fale ninc ütéi helyzet 2016.05.17. - 27-2016.05.17. - 28 - Metódu pec. - Lep void Lep(); Előre lép az adott ozlopban, ha nem tud, akkor az ozlop elejére áll é meghívja a tőle balra levőt királynő Lep() tagfüggvényét. bemenet: - kimenet: true tudott lépni fale nem tudott lépni Metódu pec. - Helyezkedj void Helyezkedj(); Megvizgála a aját pozícióját, hogy megfelelőe. Ha ütében áll, akkor meghívja Lep() tagfüggvényét. Ha tudott lépni, akkor imét megvizgálja a aját pozícióját. bemenet: - kimenet: true tudott megfelelő helyet találni magának fale nem tudott megfelelő helyet találni 2016.05.17. - 29-2016.05.17. - 30 -
Metódu pec. - Kiir void Kiir(); Kiírja a aját é a zomzédok pozícióját. Kiralyno oztály megvalóítáa cla Kiralyno { int or; // or 1-8 int ozlop; // ozlop 1-8 Kiralyno *zomzed; // zomzéd pointere Kiralyno(int o, Kiralyno *z): zomzed(z), ozlop(o) { or = 1; bool Uteben(int, int o); bool Lep(); bool Helyezkedj(); void Kiir(); ; 2016.05.17. - 31-2016.05.17. - 32 - Kiralyno oztály megvalóítáa/2 bool Kiralyno::Uteben(int, int o) { int d = ozlop - o; // ozlop differencia if (or == or + d == or - d == ) return true; ele if (zomzed!= NULL) // ha van zomzéd return zomzed->uteben(, o); // akkor azzal i ele return fale; Kiralyno oztály megvalóítáa/3 bool Kiralyno::Lep() { if (or < 8) { or++; return true; // tudott lépni if (zomzed!= NULL) { // nem tud, van zomz. if (!zomzed->lep()) return fale; if (!zomzed->helyezkedj()) return fale; ele { return fale; or = 1; return true; 2016.05.17. - 33-2016.05.17. - 34 - Kiralyno oztály megvalóítáa/4 bool Kiralyno::Helyezkedj() { while (zomzed!= NULL && zomzed->uteben(or, ozlop)) if (!Lep()) return fale; return true; void Kiralyno::Kiir() { if (zomzed!= NULL) zomzed->kiir(); cout << (char)(ozlop-1+'a') << 9-or << endl; Főprogram int main() { Kiralyno *babu = NULL; for (int i = 1; i <= 8; i++) { babu = new Kiralyno(i, babu); babu->helyezkedj(); babu->kiir(); 2016.05.17. - 35-2016.05.17. - 36 -
Megtalálja-e az egér a ajtot Egér algoritmua Minden cellából előzör jobbra, majd le, ezután balra é végül fel irányokba indul. Minden cellában otthagyja a nyomát, azaz azt, hogy onnan merre indult legutoljára. Cak olyan cellába lép be, ahol ninc "nyom". Ha már nem tud hova lépni, vizalép. 2016.05.17. - 37-2016.05.17. - 38 - Megtalálja-e az egér a ajtot Megtalálja-e az egér a ajtot 2016.05.17. - 39-2016.05.17. - 40 - Megtalálja-e az egér a ajtot Megtalálja-e az egér a ajtot 2016.05.17. - 41-2016.05.17. - 42 -
Megtalálja-e az egér a ajtot Megtalálja-e az egér a ajtot 2016.05.17. - 43-2016.05.17. - 44 - Hogyan modellezhető Réztvevők, kapcolatok, tevékenyégek labirintu cellákból épül fel a celláknak zomzédai vannak tárolja a rajta álló valamit é annak nyomát megkéri a rajta álló valamit, hogy lépjen kirajzolja az állát egér irány néz lép fal haonlít az egérhez, de nem lép Statiku modell Labirint Cella Obj n, m, poi Lép, Print zomzéd, nyom, Set.., Get.. Az attribútumok megadáa nem telje, cak vázlato! A telje program ill. dokumentáció letölthető a tárgy honlapjáról Eger irány Néz,Lépj,Lép jel, erő Lép Fal jel, erő Lép 2016.05.17. - 45-2016.05.17. - 46 - Obj metóduai Eger objektum cla Obj { protected: int ir; // ebbe az irányba tart mot Obj() :ir(-1) {; // kezdő irány Obj *Nez(int i, Cella &c, bool b = fale); void Lepj(int i, Cella &c, bool b = fale); virtual char Jele() = 0; // jel lekérdzée virtual int Ereje() = 0; // erő lekérdezée virtual void Lep(Cella &c); // léptet virtual void operator()(obj*) {; // ha "megették" ; cla Eger :public Obj { cont int ero; cont char jel; Eger(char j = 'e', int e = 10) :ero(e), jel(j) { char Jele() { return(jel); // jele int Ereje() { return(ero); // ereje void operator()(obj *p) { // meghívódik, ha megették cout << "Jaj zegeny " << Jele(); cout << " megetvett a(z):"; cout << p->jele() << " jelu\n"; ; 2016.05.17. - 47-2016.05.17. - 48 -
Cella objektum /1 cla Cella { int x, y; // geometriai koordináták Cella *z[4]; // zomzédok, ha NULL, akkor ninc Obj *p; // cella tartalma. URES, ha ninc Lita<Labnyom> ny; // lábnyomok litája enum irany { J, L, B, F ; // nehéz zépen elérni.. Cella() { SetPo(0, 0); void SetPo(int i, int j); void SetSz(int n, Cella *cp) { z[n] = cp; // zomzéd Cella *GetSz(int n) { return(z[n]);... Cella objektum /2... void SetObj(Obj *a) { p = a; // objektum beíráa Obj *GetObj() { return(p); // objektum lekérdezée void SetNyom(int n); // lábnyom beíráa int GetNyom(cont Obj *a); // lábnyom lekérdezée void DelNyom() {ny.torol(labnyom(getobj())); 2016.05.17. - 49-2016.05.17. - 50 - Főprogram (rézlet) Labirintu lépteté Labirint lab(4,5); // 4 * 5 o labirintu Eger e1, e2; // 2 egér; jele: e lab.setobj(2, 3, e1); // egerek elhelyezée lab.setobj(1, 4, e2); try { char ch; lab.print(); // kiírjuk a labirintut while (cin >> nokipw >> ch, ch!= 'e') { lab.lep(); lab.print(); // lépteté catch (exception& e) { cout << e.what() << endl; Végig kell járni a cellákat meghívni az ott "lakó" objektum léptetéét Figyelni kell. hogy nehogy duplán lépteünk. (bejárái orrend elé lépett) 2016.05.17. - 51-2016.05.17. - 52 - Obj::lep() /1 Obj::Lep() /2 if (c.getnyom(thi) < 0) // ha nem volt nyoma, indul c.setnyom(f+1); // így nem tud vizalépni if (++ir <= F) { // ha van még bejáratlan irány if (Obj *p = Nez(ir, c)) { // ha van zomzéd if (Ereje() > p->ereje()) { // haő az erőebb (*p)(thi); // meghívjuk a függv. operátorát Lepj(ir, c); // rálépünk (eltapouk) ir = -1; // mot léptünk be: kezdő irány ele { // ninc már bejáratlan irány if ((ir = c.getnyom(thi)) > F) { // kezdő nem lép viza. throw td::logic_error("kezdo pozicioba jutott"); ele { // vizalépé if (Obj *p = Nez(ir, c, true)) { // lehet, h. van ott valaki if (Ereje() > p->ereje()) { // Ő az erőebb (*p)(thi); // meghívjuk a függv. operátorát Lepj(ir, c, true); // vizalépünk é eltapouk ir ^= 2; // erre ment be (trükk: a zemben levő irányok cak a 2-e bitben különböznek) 2016.05.17. - 53-2016.05.17. - 54 -
Amőba Szereplők: tábla, korongok, játékook Ki imeri a zabályokat Tábla Korongok Válaztott megvalóítá: Tábla imeri a korongok helyzetét, zomzédokat A korongok le tudják kérdezni a zomzédokat Meg tudják állapítani, ha nyert helyzet van. Ekkor zínt váltanak. Objektum hierachia Table belő oztálya Poition beépíthető lenne a Dic oztályba, de a felelőégek így jobban elvállnak. 2016.05.17. - 55-2016.05.17. - 56 - Szomzédok é irányok typedef td::map<int, Dic*> neighbor_type; cla Table { td::vector<td::vector<dic*> > t; tatic cont int MaxDir = 8; truct dir_type { int dx, dy; dir[maxdir];... void Dic::checkAll() { Table::neighbor_type nb = po.getneighbor(); for(table::neighbor_type::iterator it= nb.begin(); it!= nb.end(); ++it) { if ((it->econd)->check(color, it->firt)) etcolor(red); Sor ellenőrzée egyik irányban bool Dic::check(color_type col,int dir,int max) { if (col == color) { if (--max == 0) { etcolor(red); return true; ele { Dic *dp = po.getnext(dir); if (dp && dp->check(col, dir, max)) { etcolor(red); return true; return fale; 2016.05.17. - 57-2016.05.17. - 58 - Objektum Programozá alapjai II. (13. ea) C++ Év végi özefoglalá Szeberényi Imre BME IIT <zebi@iit.bme.hu> M Ű E G Y E T E M 1 7 8 2 2016.05.17. - 59 - OBJEKTUM: konkrét adat é a rajta végezhető műveletek megteteítője egyedileg azonoítható vielkedéel é állapottal jellemezhető felelőége é jogköre van képe kommunikálni má objektumokkal a belő adatzerkezet, é a műveleteket megvalóító algoritmu rejtve marad könnyen módoítható újrafelhaználható általánoítható 2016.05.17. - 60 -
OO paradigmák egyégbezárá (encapulation) oztályok (adatzerkezet, műveletek özekapcoláa) többarcúág (polymorphim) műveletek paraméter függőek, tárgy függőek (köté) példányoítá (intantiation) öröklé (inheritance) generiku adatzerkezet alapú megoldáok Cla Objektum oztály objektum fajta, típu (vielkedéi oztály) Oztály Objektum Objektum Egy vielkedéi oztály egy konkrét példánya. oztály Komplex k1, k2, k3; objektumok 2016.05.17. - 61-2016.05.17. - 62 - Létrehozá, megemmiíté, értékadá Kontruktor // létrehozá default: X() // ninc paramétere automatikuan létrejön, ha ninc máik kont. máoló: X(cont X&) // referencia paramétere van, automatikuan létrejön: meghívja az adattagok é őök máoló kont.-rát, ha obj. egyébként bitenként máol. Detruktor // megemmiíté automatikuan létrejön: meghívja az adattagok é őök detruktorát operator=(cont X&) // értékadó operátor automatikuan létrejön: meghívja az adattagok é őök értékadó operátorát, ha objektum, egyébként bitenként máol. 2016.05.17. - 63 - Kontruktor é detruktor KONSTRUKTOR: Definíció é inicializálá özevonáa. DESTRUKTOR: Az objektum megzüntetée. cla Komplex { double re, im; Komplex() { // kontruktornak ninc típua Komplex(double r, double i) { re = r; im = i; ~Komplex() { // detruktornak ninc paramétere... ; Komplex k1; Komplex k2 = k1; ez az alapértelmezé ideiglene objektum // máoló (copy) kontruktorral Komplex k3 = Komplex(1.2, 3.4); 2016.05.17. - 64 - Inicializálá miért má mint az értékadá A kezdeti értékadákor még inicializálatlan a változó (nem létezik), ezért nem lehet a máoláal azono módon kezelni. Mikor hívódik a máoló kontruktor inicializálákor (azono típual inicializálunk) függvény paraméterének átadáakor függvény vizatéréi értékének átvételekor ideiglene változók özetett kifejezéekben kivétel dobáakor Detruktor feladatai Megzünteti a aját rézt: végrehajtja a programozott törzet tartalmazott objektumok detruktorainak híváa virtuáli függvénymutatók vizaállítáa virtuáli alapoztály mutatóinak vizaállítáa Hívja a közvetlen, nem virtuáli alapoztályok detruktorait. Örökléi lánc végén hívja a virtuáli alapoztályok detruktorait. 2016.05.17. - 65-2016.05.17. - 66 -
Statiku tag Az oztályban tatikuan deklarált tag nem példányoodik. Pontoan egy példány létezik, amit explicit módon definiálni kell (létre kell hozni). Minden objektum ugyanazt a tagot éri el. Nem zükége objetummal hivatkozni rá. pl: String::SetUcae(true); Statiku tagként az oztály tartalmazhatja önmagát. Felhaználá: globáli változók elrejtée Statiku tagfüggvény Cak egy példányban létezik. Statiku tagfüggvény nem éri el az objektumpéldányok nem tatiku adattagjait. cla A { int a; Nem éri el! tatic void f() { cout << a; ; 2016.05.17. - 67-2016.05.17. - 68 - Alapértelmezett tagfüggvények Kontruktor default: X() // ninc paramétere máoló: X(cont X&) // referencia paraméter Detruktor operator=(cont X&) // értékadó operator&() // címképző operator,(cont X&) // vező A kontruktor/detruktor é az értékadó operátor alapértelmezé zerint meghívja az adattagok é őök megfelelő tagfüggvényét. Ha azonban aját függvényünk van, akkor abban cak az történik, amit beleírtunk. Kivéve a kontruktor/detruktor alapfunkcióit (default létrehozá, megemmiíté.) 2016.05.17. - 69 - Operátorok kiértékelée ha a bal oldal oztály, akkor meg kell vizgálni, hogy van-e megfelelő alakú tagfüggvény ha ninc, vagy beépített típu, de a jobb oldal oztály, akkor meg kell vizgálni, hogy van-e megfelelő alakú globáli függvény Mikor kell globáli függvény ha a bal oldal nem oztály (pl. 2 + X ) vagy ninc a kezünkben (pl. cout << X) 2016.05.17. - 70 - A védelem enyhítée: friend cla Komplex { double re, im;... Komplex operator+(cont Komplex& k) { Komplex um(k.re + re, k.im + im); return(um); Komplex operator+(cont double r) { return(operator+(komplex(r))); friend otream& operator<<(otream&, cont Komplex& k); ; otream& operator<<(otream&, cont Komplex& k) << k.re << ',' << k.im << 'j'; return(); Így láncolható cout << k1 << k2; 2016.05.17. - 71 - Védelem özefoglaláa külő zármaztatott tagfüggvény é barát protected: private: 2016.05.17. - 72 -
Öröklé Az öröklé olyan implementáció é modellezéi ezköz, amelyik lehetővé tezi, hogy egy oztályból olyan újabb oztályokat zármaztaunk, melyek rendelkeznek az eredeti oztályban már definiált tulajdonágokkal, zerkezettel é vielkedéel. Újrafelhaználhatóág zinonimája. Nem cak bővíthető, hanem a tagfüggvények át i definiálhatók. 2016.05.17. - 73 - pecializáció Kompatibilitá/2 állat általánoítá madár emlő vízi galamb veréb kutya bálna ponty A típuú objektum kompatibil B-vel, ha A típuú objektum bárhol é bármikor alkalmazható, ahol B haználata megengedett. (pl: kutya kompatibili az emlőel) 2016.05.17. - 74 - Generiku oztályok é függv. Generiku oztályokkal é függvényekkel általáno zerkezetekhez jutunk: Típut paraméterként adhatunk meg. A generiku oztály v. függvény kéőbb a típunak megfelelően példányoítható. A pecializáció orán a ablonból az általánotól eltérő példány hozható létre. A függvényparaméterekből a konkrét ablonpéldány levezethető. Függvényablon átdefiniálható. template <cla T> void rendez (T a[], int n) { for (int i = 1; i < n; i++) { T tmp = a[i]; int j = i-1; while (j >= 0 && a[j] > tmp) { a[j+1] = a[j]; j--; Generiku oztályok é függv. /2 template <cla T, int > cla Array { T t[]; T& operator[](int i); ; a[j+1] = tmp; Array<int, 10> i10; Array<double, 5> d5; Array<char*, 20> cp20; int t[100]; rendez<int>(t, 100); 2016.05.17. - 75-2016.05.17. - 76 - Predikátumok Predikátumok /2 Az algoritmuok tovább általánoíthatók ún. predikátumokkal. Ezek a logikai függvények, vagy függvényobjektumok befolyáolják az algoritmut működéét. template <cla T, bool Ha(T, T)> void rendez (T a[], int n) { for (int i = 1; i < n; i++) { T tmp = a[i]; int j = i-1; while (j >= 0 && Ha(a[j], tmp)) { a[j+1] = a[j]; j--; a[j+1] = tmp; int t[100]; rendez<int, haonlitfv>(t, 100); Template paraméterként átadott predikátumok. template<cla T> bool haonlitfv(t a, T b) { return a > b; template<> bool haonlitfv<char*>(char* a, char* b) { // pecializáció return trcmp(a, b) >= 1; int t[6] = { 1, 2, -8, 0, 12, 3 ; rendez<int, haonlitfv<int> >(t, 6); char *txt[] = { "zilva", "alma", "korte" ; rendez<char*, haonlitfv<char*> >(txt, 3); 2016.05.17. - 77-2016.05.17. - 78 -
Predikátumok /3 Függvényparaméterként átadott predikátumok: template<cla T, cla S> T kivalazt(t a[], int n, S cmp) { ilyen fv. poi T tmp = a[0]; for (int i = 1; i < n; i++) if (cmp(a[i], tmp)) tmp = a[i]; return tmp; template<cla T> bool haonlitfv(t a, T b) { return a > b; int t[6] = { 1, 2, -8, 0, 12, 3 ; kivalazt<int, bool (*)(int,int)>(t, 6, HaonlitFv<int>); kivalazt(t, 6, haonlitfv<int>);// kitalálja templ. par. Bejárók Tárolók -> adatorozatok tároláa adatorozat elemeit el kell érni tipiku művelet: "add a következőt" Iterátor: általánoított adatorozat elemeire hivatkozó elvont mutatóobjektum. Legfontoabb műveletei: éppen akt. elem elérée (* ->) következő elemre lépé (++) mutatók özehaonlítáa ( ==,!= ) mutatóobjektum létrehozáa az elő elemre ( begin() ) mutatóobjektum létrehozáa az utoló utáni elemre ( end() ) 2016.05.17. - 79-2016.05.17. - 80 - Bejárók /2 Kivételkezelé = globáli goto Nem kell imerni a tároló belő adatzerkezetét. Tároló könnyen változtatható. Generiku algoritmuok fel tudják haználni. Indexelé nem mindig alkalmazható, de iterátor.. A pointer az iterátor egy peciái fajtája. Kivétel2 Kritiku műveletek Kivétel1 template<cla Iter> void PrintFv(Iter firt, Iter lat){ while (firt!= lat) cout << *firt++ << endl; int tarolo[5] = { 1, 2, 3, 4, 5 ; PrintFv<int*>(tarolo, tarolo+5); Array<double, 10> d10; PrintFv<>(d10.begin(), d10.end()); További műv. 2016.05.17. - 81-2016.05.17. - 82 - Kivételkezelé/2 A dobott kivétel alap ill. zármaztatott objektum i lehet. try { throw E(); catch(h) { // mikor jut ide 1. H é E azono típuú, 2. H bázioztálya E-nek, 3. H é E mutató é teljeül rájuk 1. vagy 2., 4. H é E referencia é teljeül rájuk 1. vagy 2. Kivételkezelé/3 Célzerű kivétel oztályokat alkalmazni, (pl. td::exception) amiből zármaztatáal újabb kivételeket lehet létrehozni. A dobá értékparamétert dob, ezért az elkapákor zámolni kell az alapoztályra történő konverzióval (adatvezté). Célzerű pointert, vagy referenciát alkalmazni. Kell máoló kontruktor. 2016.05.17. - 83-2016.05.17. - 84 -
Szabványo kivételek (tdexcept) bad_alloc bad_cat bad_typeid bad_exception io_bae::failure range_error overflow_error undeflow_error lenght_error domain_error out_of_range invalid_argument runtime_error exception logic_error Szabványo kivételek/2 cla exeption {... Aut. típukonverzió letiltáa exception() throw(); exception(cont exception&) throw(); execption& operator=(cont exception&) throw(); virtual ~exception() throw(); virtual cont char *what() cont throw(); ; cla runtime_error : public exception { explicit runtime_error(cont tring& what_arg); ; cla logic_error : public exception { explicit logic_error(cont tring& what_arg ); ; 2016.05.17. - 85-2016.05.17. - 86 - Szabványo kivételek/3 A tandard könyvtár nem bővíti az exception oztály függvényeit, cak megfelelően átdefiniálja azokat. A felhaználói programnak nem köteleége az exceptionből zármaztatni, de célzerű. try {... referencia catch (exception& e) { cout << "exeptionból zármazik" cout << e.what() << endl; catch (...) { cout << "Ez valami má\n"; Szabványo könyvtár (STL) Általáno célú, újrafelhaználható elemek: tárolók, majdnem tárolók algoritmuok függvények bejárók memóriakezelők adatfolyamok http://www.gi.com/tech/tl/ http://www.cppreference.com/cpptl.html http://www.cpluplu.com/reference/tl/ 2016.05.17. - 87-2016.05.17. - 88 - Tárolók (konténerek) Szabványo tárolók Tetzőlege adatok tároláára Sorban, vagy tetzőlege orrendben érhetők el az adatok. Tipizált felületek vector<int> i1(10, -3); vector<double> d1(100); i1[8] = 12; i1.at(9) = 13; for (vector<double>::ize_type i = 0; i < d1.ize(); i++) d1[i] = 3.14; for (vector<int>::iterator i = i1.begin(); i < i1.end(); i++) cout << *i << endl; vector lit deque tack queue priority_queue map multimap et multiet tring array valarray bitet 2016.05.17. - 89-2016.05.17. - 90 -
STL tárolók özefoglaláa A tárolók nem cak tárolják, hanem "birtokolják i az elemeket" elemek létrehozáa/megzüntetée Két fajta STL tároló van: Sorozat tárolók (vector, lit, deque) A programozó határozza meg a orrendet: Azociatív tárolók (et, multiet, map, multimap) A tároló határozza meg a tárolt orrendet Ez elemek egy kulccal érhetők el. STL tárolók özefoglaláa /2 vector<t, Alloc> lit<t, Alloc> deque<t, Alloc> map<key, T, Cmp, Alloc> et<key, Cmp, Alloc> tack<t, deque> queue<t, deque> priority_queue<t, vector, Cmp> 2016.05.17. - 91-2016.05.17. - 92 - Tárolók fontoabb műveletei Kontr. detr. op= Iterátoro k i z e m a x _ i z e e m p t y r e i z e fr o n t vector + + + + + + + + + + + + + + + + + deque + + + + + + + + + + + + + + + + + + + b a c k lit + + + + + + + + + + + + + + + + + o p [] a t a i g n i n e rt e r a e w a p et + + + + + + + + + multiet + + + + + + + + + map + + + + + + + + + + multimap + + + + + + + + + c l e a r p u h _ fr o n t p o p _ fr o n t p u h _ b a c k p o p _ b a c k Algoritmuok <algorithm> Nem módoító orozatműveletek Sorozatmódoító műveletek Rendezé, rendezett orozatok műveletei Halmazműveletek Kupacműveletek Mimimum, maximum Permutációk 2016.05.17. - 93-2016.05.17. - 94 - Függvényobjektumok <functional> unary_function, binary_function template <cla Arg, cla Reult> truct unary_function { typedef Arg argument_type; typedef Reult reult_type; ; truct Valami : public uanry_function<int, bool> {... ;... Valami::argument_type... Valami::reult_type...... 2016.05.17. - 95 - Predikátumok é aritm. műv. equal_to, not_equal_to, greater, le, greater_equal, le_equal logical_and, logical_or logical_not plu minu multiplie divide modulu negate 2016.05.17. - 96 -
Lekötők, átalakítók, típuok Nem cak C++-t tanultunk! bind2nd() bind1t() mem_fun() mem_fun_ref() prt_fun() not1() not2() binder1t binder2nd mem_fun1_ref_t mem_fun1_t mem_fun_ref_t mem_fun_t unary_negate binary_negate OO tervezé dolgok zereplők zámbavétele vielkedéük modellezée újrafelhaználhatóág, generikuág OO modell leíráa Fejleztő környezet Dokumentálá pici UNIX 2016.05.17. - 97-2016.05.17. - 98 - Modellezéi példa 1. Terv: elvi kapcolati zint Modellezzük hallgatók, tantárgyak, feleletek kapcolatát: Hallgatók tárgyakat vehetnek fel Tárgyakhoz zámonkéréek tartoznak Számonkéréek eredményét tárolni kell Mik az olbjektumok (zereplők) Ki miért felel Ki mihez férhet hozzá Ki milyen interfézt ad 2016.05.17. - 99-2016.05.17. - 100 - Megvalóítái zint Kik a zereplők Ki miért felel Mihez férhet hozzá Milyen interfézt ad Modell: heterogén koll. Óceán olyan alapobjektumra mutató pointert tárol mely objektumból zármaztatható hal, cápa, tb. Óceán ciklikuan bejárja a tárolót é a pointerek egítégével minden objektumra meghív egy metódut, ami a vielkedét zimulálja. Minden ciklu végén kirajzolja az új populációt. 2016.05.17. - 101-2016.05.17. - 102 -
Statiku modell Modellezéi példa kieg. Ocean cellak[n][m] lep Hal kor lep Obj lep Capa kor nemevett lep Egézítük ki a korábbi modellünket: Az állatvédők tudni akarják, hogy mekkora utat tez meg élete orán Cápeti, a cápa. A tengerbiológuok tudni akarják, hogy hányzor zaporodik Cápeti. A dokumentum film kézül Cápeti útjáról. Kérdéek: Tegyünk 3 jeladót Cápeti nyakába 1 jeladó jelezzen mindenkinek 2016.05.17. - 103-2016.05.17. - 104 - Oberver terv. minta A forma i fonto! ConcreteOb1 +update( ) Oberver -ubjptr +update( ) ConcreteOb2 +update( ) Subject -obptr[] +attach() +detach() +notify() ConcreteSubj main(l,a,n,d)char**a;{ for(d=atoi(a[1])/10*80- atoi(a[2])/5-596;n="@nka\ CLCCGZAAQBEAADAFaISADJABBA^\ SNLGAQABDAXIMBAACTBATAHDBAN\ ZcEMMCCCCAAhEIJFAEAAABAfHJE\ TBdFLDAANEfDNBPHdBcBBBEA_AL\ H E L L O, W O R L D! " [l++-3];)for(;n-->64;) putchar(!d+++33^ l&1); 2016.05.17. - 105-2016.05.17. - 106 - WhereAmI 47 19!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! UNIX-zal kezdtük a félévet Néhány gondolat a UNIX-o fejleztőezközökről befejezéül: Számtalan ezköz, többek által ma már elavultnak tekintett, ugyanakkor hatékony, egyége parancoro felülettel. Kiemelt a zövegfeldolgozá/elemzé hatékony támogatáa. Egyre több next, next, next, finih program, a PC- változatokban, ami nem mindig jelent előnyt. 2016.05.17. - 107-2016.05.17. - 108 -
Fejleztét egítő ezközök make cc, rc, cv, vn, git prof lex (flex) yacc (bion) awk perl... lex (cak gondolatébreztőként) Lexikai analizátor generátor Regulári kifejezéekkel megadott lexikai elemek felimerééhez C programot generál. Önállóan i felhaználható ( ll), de legtöbbzör beépítik egy máik programba. 2016.05.17. - 109-2016.05.17. - 110 - yacc (cak gondolatébreztőként) Compiler generáló ezköz környezetfüggetlen nyelvhez. A nyelvtani zabályokból előállítja a nyelvtant felimerő C programot. Önállóan i haználható (-ly), de legtöbbzör beépítik máik programba. Péda: római zámok konverziója %token RDIG %{ int lat = 0; % %% lit: lit '\n' lit number '\n' { printf("-> %d\n", $2); lat = 0; lit error '\n' { yyerrok; ; number: RDIG { lat = $$=$1; RDIG number { if ($1 >= lat) $$ = $2 + (lat=$1); ele $$ = $2 - (lat=$1); ; 2016.05.17. - 111-2016.05.17. - 112 - romailex.l Közönöm a figyelmet % extern int yylval; % %% I { yylval= 1; return RDIG; V { yylval= 5; return RDIG; X { yylval= 10; return RDIG; L { yylval= 50; return RDIG; C { yylval= 100; return RDIG; D { yylval= 500; return RDIG; M { yylval=1000; return RDIG; [^IVXLCDM] { return(yytext[0]); 2016.05.17. - 113-2016.05.17. - 114 -