Folytatjuk állatorvosi sorozatunkat, ha ezt olvasod, akkor feltételezhetően már túl vagy az alábbi, erősorrendben hivatkozott posztokon:
- a Tömör a gyönyörben kifejlesztettünk egy C struktúrás LZW (bináris) fa építőt
- mélyebben megismerkedhettél a kóddal a Labormérés otthon, avagy hogyan dolgozok fel egy példát posztban
- amit jó (K&R) szokás szerint továbbfejlesztések során át elkezdtünk átteni C++-ba
- továbbá a kezdő PolarGen és a saját Verem osztályod 12 változata után sikerrel vetted a "9-10" labort, ahol "sablonosítottuk a vermet", majd végül a BinFa osztályt is.
Ez a poszt is ebbe a sorozatba illeszkedik, most azt a verziót tárgyaljuk részletesen, amit már így tudsz használni:
int main () { BinFa<std::string> binSzoFa; std::string s; while (std::cin >> s) { binSzoFa << s; } std::cout << binSzoFa; binSzoFa.szabadit (); return 0; }
fordítás, futtatás például:
[norbi@sgu 9-10]$ g++ mains.cpp -o z14
[norbi@sgu 9-10]$ ./z14
dio dio alma korte piszke ribizli dio alma
------------ribizli(1, 3)
---------piszke(1, 2)
------korte(1, 1)
---dio(3, 0)
------alma(2, 1)
vagy éppen:
int main () { BinFa<Int> binSzamFa; Int n; while (std::cin >> n) { binSzamFa << n; } std::cout << binSzamFa; binSzamFa.szabadit (); return 0; }
[norbi@sgu 9-10]$ g++ maini.cpp int.cpp -o z14int
[norbi@sgu 9-10]$ ./z14int
55 45 64 64 55 23 11 99 99
---------99(2, 2)
------64(2, 1)
---55(2, 0)
------45(1, 1)
---------23(1, 2)
------------11(1, 3)
Tekerj tovább a forrásokért és a kód tárgyalásáért:
int.h
#ifndef INT__H #define INT__H #include <iostream> class Int { public: Int (int n=0):ertek (n) {}; ~Int () {}; Int (const Int &n) { ertek = n.ertek; } Int & operator= (const Int &n); int compare(Int& n); Int operator+(const Int& n) const ; Int& operator+=(const Int& n); friend std::ostream& operator<< (std::ostream& os, const Int& n); friend std::istream& operator>> (std::istream& is, Int& n); private: int ertek; }; #endif
int.cpp
#include "int.h" Int& Int::operator= (const Int &n) { ertek = n.ertek; return *this; } int Int::compare(Int& n) { if (ertek == n.ertek) return 0; else if (ertek > n.ertek) return 1; else return -1; } Int Int::operator+(const Int& n) const { return Int(ertek + n.ertek); } Int& Int::operator+=(const Int& n) { ertek += n.ertek; return *this; } std::ostream& operator<< (std::ostream& os, const Int& n) { os << n.ertek; return os; } std::istream& operator>> (std::istream& is, Int& n) { int ertek; is >> ertek; n = Int(ertek); return is; }
binfa.h
#ifndef BIN_FA__H #define BIN_FA__H #include <iostream> template <class CsomopontTartalomTipus> class BinFa { class Csomopont { public: Csomopont (CsomopontTartalomTipus s):szo (s), hanyszor (1), bal (0), jobb (0) {}; ~Csomopont () {}; Csomopont *balra () { return bal; } Csomopont *jobbra () { return jobb; } void balra (Csomopont * bal) { this->bal = bal; } void jobbra (Csomopont * jobb) { this->jobb = jobb; } CsomopontTartalomTipus & tartalma () { return szo; } void novel () { ++hanyszor; } int volt () { return hanyszor; } private: friend class BinFa <CsomopontTartalomTipus>; CsomopontTartalomTipus szo; int hanyszor; Csomopont *bal; Csomopont *jobb; Csomopont (const Csomopont &); Csomopont & operator= (const Csomopont &); }; Csomopont *gyoker; Csomopont *csomopont; int melyseg; void kiir (Csomopont * elem, std::ostream& os); void szabadit (Csomopont * elem); BinFa (const BinFa &); BinFa & operator= (const BinFa &); public: BinFa ():gyoker (0), csomopont (0) {} ~BinFa () { if (gyoker) szabadit(); } void operator<< (CsomopontTartalomTipus s); friend std::ostream& operator<< (std::ostream& os, BinFa& bf) { bf.kiir(os); return os; } void kiir (std::ostream& os) { melyseg = 0; kiir (gyoker, os); } void kiir (void) { melyseg = 0; kiir (gyoker, std::cout); } void szabadit (void) { szabadit (gyoker); gyoker = 0; } }; template <class CsomopontTartalomTipus> void BinFa<CsomopontTartalomTipus>::operator<< (CsomopontTartalomTipus s) { int e; if (csomopont == NULL) { csomopont = new Csomopont (s); gyoker = csomopont; } else if ((e = csomopont->tartalma ().compare (s)) == 0) { csomopont->novel (); } else if (e > 0) { if (csomopont->balra () == NULL) { csomopont->balra (new Csomopont (s)); } else { csomopont = csomopont->balra (); *this << s; } } else if (e < 0) { if (csomopont->jobbra () == NULL) { csomopont->jobbra (new Csomopont (s)); } else { csomopont = csomopont->jobbra (); *this << s; } } csomopont = gyoker; } template <class CsomopontTartalomTipus> void BinFa<CsomopontTartalomTipus>::kiir (Csomopont * elem, std::ostream& os) { if (elem != NULL) { ++melyseg; kiir (elem->jobb, os); // ez a postorder bejáráshoz képest // 1-el nagyobb mélység, ezért -1 for (int i = 0; i < melyseg; ++i) os << "---"; os << elem-> tartalma () << "(" << elem->volt () << ", " << melyseg - 1 << ")" << std::endl; kiir (elem->bal, os); --melyseg; } } template <class CsomopontTartalomTipus> void BinFa<CsomopontTartalomTipus>::szabadit (Csomopont * elem) { if (elem != NULL) { szabadit (elem->jobb); szabadit (elem->bal); delete elem; } } #endif