Gyakorló feladatok (10. hét)

Fontosabb kulcsszavak, fogalmak

  • Standard Template Library (STL)
  • Tárolók, tárolók műveletei
  • Sorozattárolók
  • Asszociatív tárolók
  • Generikus algoritmusok
  • Iterátorok

Feladatok megoldásokkal

  1. Ismételjük át sorozattárolók közös metódusait és az std::vektor speciális metódusait az az STL összefoglaló alapján: http://infocpp.iit.bme.hu/sites/default/files/proga2/stlsummary.pdf! A közös metódusok hasonlítanak a korábban készített gyak::Array tárolónk metódusaihoz. A hasonlóság nem véletlen!
  2. Magától értetődő, de talán mégis érdemes megnézni, hogy többdimenziós vektort (mátrixot) hogyan lehet létrehozni. Mit ír ki a következő kódrészlet?
    	
    vector<vector<int> > d2int(5, vector<int>(10, 3));
    for (size_t i = 0; i < 5; i++) {
        for (size_t j = 0; j < 10; j++) 
            std::cout << d2int[i][j] << " ";
        std::cout << endl;
    }
    
  3. Készítsünk általános kiíró függvényt a hasonló felépítésű mátrixokhoz! Milyen tárolókkal működik?
  4. Vektor, lista iterator: hozzunk létre tömbből vektort, majd abból listát iterátorral:
  5. Csapatokat szeretnénk alkotni. Első körben a csapatnak csak neve van (egyedi) és a csapat tagoknak is csak neve van (csapaton belül egyedi). Szeretnénk mindenféle okos névsorokat gyártani. Ha csak a neveket kell tárolni, akkor ez a fésűs listának kinéző feladat halmazok map-jével megoldható:
    std::map<std::string, std::set<std::string> > csapatok;
    

    A csapatnevek egyediségét a map, a csapattagok nevének csapaton belüli egyediségét pedig a set biztosítja. Olvassunk névpárokat a standard inputról (csapat, tag), és tegyük bele a tárolónkba:


    Írjuk ki a neveket csapatonként rendezve! Mind a map, mind a set rendezve tárol, ezért csak be kell járnunk a tárolókat és kiírni. A bejáráshoz használhatjuk a for_each algoritmust, ami minden elemre meghív egy függvényt/funktort. Ez egy pair-t fog paraméterként kapni, aminek ez első eleme a csapat neve, a második pedig a csapattagok halmaza. Ezt a halmazt kell bejárnunk a csapattagok nevének kiírásához. Kevésbé igényesen, de kiírás ostream_iterátorral is elvégezhető.
  6. Alakítsunk ki egy olyan fésűs tárolót, amiben Jatekos pointereket tárolunk! A játékos legyen a legegyszerűbb szerkezetű, mivel nem ez most a lényeg:
    class Jatekos {
        std::string nev;
        int pont;
    public:
        Jatekos(std::string n, int p) :nev(n), pont(p) {}
        int getPont() const { return pont; }
        std::string getNev() const { return nev; }
    };
    
    std::ostream& operator<<(std::ostream& os, const Jatekos& j) {
        os << j.getNev() << " " << j.getPont();
        return os;
    }

    A fésű gerincének megvalósításához itt is kézenfekvőnek tűnik a map. Mivel valósítsuk meg a fésű fogait? Miben tároljuk a pointereket?

    • set - ettől nem lesznek a játékosnevek egyediek, de az az elemek elérése egyszerű, van find, amivel a beszúrás előtt könnyen tesztelhető a név egyedisége
    • list - kézenfekvő megoldás, de nincs find, nincs at/[]
    • map - van find, van at/[], de bejárás macerásabb a pair miatt
    • vector - nincs find, de van at/[]
    • deque - nincs find, de van at/[]

    A fentiek alapján adott feladatra talán a set tűnik legalkalmasabbnak a find léte miatt, de rá kell jönnünk, hogy a find nem használható az adott nevű csapattag megkeresésére, mivel azzal egy adott pointert kereshetnénk, nem nevet. Hasonló okokból a csapaton belüli automatikus rendezettséget, mint előnyt is elvesztettük. Így a set alkalmazása már nem tűnik jónak, sőt a rendezésnél nehézségeink is lehetek, ha utólag szeretnénk a halmaz elemeit rendezni. Ezzel szemben a halmaz sablon második paramétereként megadható egy alkalmas összehasonlító függvény, amivel a szükséges rendezettség megtartható. Ennek ellenére a gyakorlás kedvéért a halmaz helyett használjunk mást: válasszuk a list tárolót, és próbáljuk névsorban rendezetten tartani:

  7. Visszatekintve az előző két feladatra, érdemes a tárolók különbségének okán elgondolkodni. A pointeres esetben set nyújtotta előnyöket egyáltalán nem tudtuk kihasználni. Mi ennek az oka? Az, hogy pointeres esetben a rendezési szempontot nem a tárolt adat adja (ha nem írunk saját hasonlítót a set-hez ill. a map-hez). Ha a pointerek helyett objektumokat tárolnánk, akkor a tároláskor alapértelmezetten használt összehasonlítás (less) művelete az objektum szintjén felüldefiniálható lenne. Nézzük meg így a feladatot:
Utolsó frissítés: 2018-04-19 23.00