Advertisement
Guest User

lzwbin_beauty

a guest
Mar 27th, 2013
131
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 27.73 KB | None | 0 0
  1. /*$T indentinput.cpp GC 1.140 03/26/13 23:33:53 */
  2.  
  3. /*
  4.  * z3a7.cpp ;
  5.  * * Együtt támadjuk meg:
  6.  * http://progpater.blog.hu/2011/04/14/egyutt_tamadjuk_meg ;
  7.  * LZW fa építő 3. C++ átirata a C valtozatbol (+mélység, atlag és
  8.  * szórás) ;
  9.  * Programozó Páternoszter ;
  10.  * * Copyright (C) 2011, 2012, Bátfai Norbert, [email protected],
  11.  * * This program is free software: you can redistribute it and/or modify ;
  12.  * it under the terms of the GNU General Public License as published by ;
  13.  * the Free Software Foundation, either version 3 of the License, or ;
  14.  * (at your option) any later version. ;
  15.  * * This program is distributed in the hope that it will be useful, ;
  16.  * but WITHOUT ANY WARRANTY;
  17.  * without even the implied warranty of ;
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;
  19.  * GNU General Public License for more details. ;
  20.  * * You should have received a copy of the GNU General Public License ;
  21.  * along with this program. If not, see <http://www.gnu.org/licenses/>. ;
  22.  * * Ez a program szabad szoftver;
  23.  * terjeszthetõ illetve módosítható a ;
  24.  * Free Software Foundation által kiadott GNU General Public License ;
  25.  * dokumentumában leírtak;
  26.  * akár a licenc 3-as, akár (tetszõleges) késõbbi ;
  27.  * változata szerint. ;
  28.  * * Ez a program abban a reményben kerül közreadásra, hogy hasznos lesz, ;
  29.  * de minden egyéb GARANCIA NÉLKÜL, az ELADHATÓSÁGRA vagy VALAMELY CÉLRA ;
  30.  * VALÓ ALKALMAZHATÓSÁGRA való származtatott garanciát is beleértve. ;
  31.  * További részleteket a GNU General Public License tartalmaz. ;
  32.  * * A felhasználónak a programmal együtt meg kell kapnia a GNU General ;
  33.  * Public License egy példányát;
  34.  * ha mégsem kapta meg, akkor ;
  35.  * tekintse meg a <http://www.gnu.org/licenses/> oldalon. ;
  36.  * * ;
  37.  * Version history: ;
  38.  * * 0.0.1, http://progpater.blog.hu/2011/02/19/gyonyor_a_tomor ;
  39.  * 0.0.2, csomópontok mutatóinak NULLázása (nem fejtette meg senki :) ;
  40.  * 0.0.3,
  41.  * http://progpater.blog.hu/2011/03/05/labormeres_otthon_avagy_hogyan_dolgozok_fel_egy_pedat
  42.  * ;
  43.  * 0.0.4, z.cpp: a C verzióból svn: bevezetes/C/ziv/z.c átírjuk C++-ra ;
  44.  * http://progpater.blog.hu/2011/03/31/imadni_fogjatok_a_c_t_egy_emberkent_tiszta_szivbol
  45.  * ;
  46.  * 0.0.5, z2.cpp: az fgv(*mut)-ok helyett fgv(&ref) ;
  47.  * 0.0.6, z3.cpp: Csomopont beágyazva ;
  48.  * http://progpater.blog.hu/2011/04/01/imadni_fogjak_a_c_t_egy_emberkent_tiszta_szivbol_2
  49.  * ;
  50.  * 0.0.6.1 z3a2.c: LZWBinFa már nem barátja a Csomopont-nak, mert annak tagjait
  51.  * nem használja direktben ;
  52.  * 0.0.6.2 Kis kommentezést teszünk bele 1. lépésként (hogy a kicsit lemaradt
  53.  * hallgatóknak is ;
  54.  * könnyebb legyen, jól megtűzdeljük további olvasmányokkal) ;
  55.  * http://progpater.blog.hu/2011/04/14/egyutt_tamadjuk_meg ;
  56.  * (majd a 2. lépésben "beletesszük a d.c-t", majd s 3. lépésben a
  57.  * parancssorsor argok feldolgozását) ;
  58.  * 0.0.6.3 z3a2.c: Fejlesztgetjük a forrást:
  59.  * http://progpater.blog.hu/2011/04/17/a_tizedik_tizenegyedik_labor ;
  60.  * 0.0.6.4 SVN-beli,
  61.  * http://www.inf.unideb.hu/~nbatfai/p1/forrasok-SVN/bevezetes/vedes/ ;
  62.  * 0.0.6.5 2012.03.20, z3a4.cpp: N betűk (hiányok), sorvégek, vezető komment
  63.  * figyelmen kívül: http://progpater.blog.hu/2012/03/20/a_vedes_elokeszitese ;
  64.  * 0.0.6.6 z3a5.cpp: mamenyaka kolléga észrevételére a több komment sor
  65.  * figyelmen kívül hagyása ;
  66.  * http://progpater.blog.hu/2012/03/20/a_vedes_elokeszitese/fullcommentlist/1#c16150365
  67.  * ;
  68.  * 0.0.6.7 Javaslom ezt a verziót választani védendő programnak ;
  69.  * 0.0.6.8 z3a7.cpp: pár kisebb javítás, illetve a védések támogatásához
  70.  * további komment a << ;
  71.  * eltoló operátort tagfüggvényként, illetve globális függvényként
  72.  * túlterhelő részekhez. ;
  73.  * http://progpater.blog.hu/2012/04/10/imadni_fogjak_a_c_t_egy_emberkent_tiszta_szivbol_4/fullcommentlist/1#c16341099
  74.  * ;
  75.  */
  76. #include <iostream> /* mert olvassuk a std::cin, írjuk a std::cout csatornákat */
  77. #include <cmath>    /* mert vonunk gyököt a szóráshoz: std::sqrt */
  78. #include <fstream>  /* fájlból olvasunk, írunk majd */
  79.  
  80. /*
  81.  =======================================================================================================================
  82.     Az LZWBinFa osztályban absztraháljuk az LZW algoritmus bináris fa építését. Az osztály definíciójába
  83.     beágyazzuk a fa egy csomópontjának az absztrakt jellemzését, ez lesz a beágyazott Csomopont osztály. Miért
  84.     ágyazzuk be? Mert külön nem szánunk neki szerepet, ezzel is jelezzük, hogy csak a fa részeként számiolunk
  85.     vele.
  86.  =======================================================================================================================
  87.  */
  88. class   LZWBinFa
  89. {
  90. /*
  91.  -----------------------------------------------------------------------------------------------------------------------
  92.  -----------------------------------------------------------------------------------------------------------------------
  93.  */
  94. public:
  95.  
  96.     /*
  97.      ===================================================================================================================
  98.         Szemben a bináris keresőfánkkal (BinFa osztály)
  99.         http://progpater.blog.hu/2011/04/12/imadni_fogjak_a_c_t_egy_emberkent_tiszta_szivbol_3 itt (LZWBinFa osztály) a fa
  100.         gyökere nem pointer, hanem a '/' betüt tartalmazó objektum, lásd majd a védett tagok között lent: Csomopont
  101.         gyoker;
  102.         A fa viszont már pointer, mindig az épülő LZW-fánk azon csomópontjára mutat, amit az input feldolgozása
  103.         során az LZW algoritmus logikája diktál: http://progpater.blog.hu/2011/02/19/gyonyor_a_tomor Ez a konstruktor
  104.         annyit csinál, hogy a fa mutatót ráállítja a gyökérre. (Mert ugye laboron, blogon, előadásban tisztáztuk,
  105.         hogy a tartalmazott tagok, most "Csomopont gyoker" konstruktora előbb lefut, mint a tagot tartalmazó LZWBinFa
  106.         osztály konstruktora, éppen a következő, azaz a fa=&gyoker OK.)
  107.      ===================================================================================================================
  108.      */
  109.     LZWBinFa() :
  110.     fa(&gyoker)
  111.     { }
  112.  
  113.     /*
  114.      ===================================================================================================================
  115.      ===================================================================================================================
  116.      */
  117.     ~   LZWBinFa()  { szabadit(gyoker.egyesGyermek()); szabadit(gyoker.nullasGyermek()); }
  118.  
  119.     /*
  120.      ===================================================================================================================
  121.         Tagfüggvényként túlterheljük a << operátort, ezzel a célunk, hogy felkeltsük a hallgató érdeklődését,
  122.         mert ekkor így nyomhatjuk a fába az inputot: binFa << b;
  123.         ahol a b egy '0' vagy '1'-es betű. Mivel tagfüggvény, így van rá "értelmezve" az aktuális (this "rejtett
  124.         paraméterként" kapott ) példány, azaz annak a fának amibe éppen be akarjuk nyomni a b betűt a tagjai (pl.:
  125.         "fa", "gyoker") használhatóak a függvényben. A függvénybe programoztuk az LZW fa építésének algoritmusát
  126.         tk.: http://progpater.blog.hu/2011/02/19/gyonyor_a_tomor a b formális param az a betű, amit éppen be kell nyomni
  127.         a fába. a binFa << b (ahol a b majd a végén látszik, hogy már az '1' vagy a '0') azt jelenti
  128.         tagfüggvényként, hogy binFa.operator<<(b) (globálisként így festene: operator<<(binFa, b) )
  129.      ===================================================================================================================
  130.      */
  131.     void operator<<(char b)
  132.     {
  133.  
  134.         /* Mit kell betenni éppen, '0'-t? */
  135.         if(b == '0')
  136.         {
  137.  
  138.             /*
  139.              * Van '0'-s gyermeke az aktuális csomópontnak? megkérdezzük Tőle, a "fa"
  140.              * mutató éppen reá mutat
  141.              */
  142.             if(!fa->nullasGyermek())    /* ha nincs, hát akkor csinálunk */
  143.             {
  144.  
  145.                 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  146.                 /* elkészítjük, azaz páldányosítunk a '0' betű akt. parammal */
  147.                 Csomopont   *uj = new Csomopont('0');
  148.                 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  149.  
  150.                 /*
  151.                  * az aktuális csomópontnak, ahol állunk azt üzenjük, hogy ;
  152.                  * jegyezze már be magának, hogy nullás gyereke mostantól van ;
  153.                  * küldjük is Neki a gyerek címét:
  154.                  */
  155.                 fa->ujNullasGyermek(uj);
  156.  
  157.                 /* és visszaállunk a gyökérre (mert ezt diktálja az alg.) */
  158.                 fa = &gyoker;
  159.             }
  160.             else    /* ha van, arra rálépünk */
  161.             {
  162.  
  163.                 /* azaz a "fa" pointer már majd a szóban forgó gyermekre mutat: */
  164.                 fa = fa->nullasGyermek();
  165.             }
  166.         }
  167.  
  168.         /* Mit kell betenni éppen, vagy '1'-et? */
  169.         else
  170.         {
  171.             if(!fa->egyesGyermek())
  172.             {
  173.                 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  174.                 Csomopont   *uj = new Csomopont('1');
  175.                 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  176.  
  177.                 fa->ujEgyesGyermek(uj);
  178.                 fa = &gyoker;
  179.             }
  180.             else
  181.             {
  182.                 fa = fa->egyesGyermek();
  183.             }
  184.         }
  185.     }
  186.  
  187.     /*
  188.      ===================================================================================================================
  189.         A bejárással kapcsolatos függvényeink (túlterhelt kiir-ók, atlag, ratlag stb.) rekurzívak, tk. a rekurzív
  190.         fabejárást valósítják meg (lásd a 3. előadás "Fabejárás" c. fóliáját és társait) (Ha a rekurzív
  191.         függvénnyel általában gondod van => K&R könyv megfelelő része: a 3. ea. izometrikus részében ezt
  192.         "letáncoltuk" :) és külön idéztük a K&R álláspontját::)
  193.      ===================================================================================================================
  194.      */
  195.     void kiir(void)
  196.     {
  197.  
  198.         /*
  199.          * Sokkal elegánsabb lenne (és más, a bevezetésben nem kibontandó reentráns
  200.          * kérdések miatt is, mert ;
  201.          * ugye ha most két helyről hívják meg az objektum ilyen függvényeit, tahát
  202.          * ha kétszer kezd futni az ;
  203.          * objektum kiir() fgv.-e pl., az komoly hiba, mert elromlana a mélység...
  204.          * tehát a mostani megoldásunk ;
  205.          * nem reentráns) ha nem használnánk a C verzióban globális változókat, a
  206.          * C++ változatban példánytagot a ;
  207.          * mélység kezelésére: http://progpater.blog.hu/2011/03/05/there_is_no_spoon
  208.          */
  209.         melyseg = 0;
  210.  
  211.         /*
  212.          * ha nem mondta meg a hívó az üzenetben, hogy hova írjuk ki a fát, akkor a ;
  213.          * sztenderd out-ra nyomjuk
  214.          */
  215.         kiir(&gyoker, std::cout);
  216.     }
  217.  
  218.     /*
  219.      * már nem használjuk, tartalmát a dtor hívja void szabadit (void) { szabadit
  220.      * (gyoker.egyesGyermek ());
  221.      * szabadit (gyoker.nullasGyermek ());
  222.      * // magát a gyökeret nem szabadítjuk, hiszen azt nem mi foglaltuk a szabad
  223.      * tárban (halmon). } ;
  224.      * A változatosság kedvéért ezeket az osztálydefiníció (class LZWBinFa {...};
  225.      * ) után definiáljuk, hogy kénytelen légy az LZWBinFa és a :: hatókör
  226.      * operátorral minősítve definiálni :) l. lentebb
  227.      */
  228.     int     getMelyseg(void);
  229.     double  getAtlag(void);
  230.     double  getSzoras(void);
  231.  
  232.     /*
  233.      * Vágyunk, hogy a felépített LZW fát ki tudjuk nyomni ilyenformán: std::cout
  234.      * << binFa;
  235.      * de mivel a << operátor is a sztenderd névtérben van, de a using namespace
  236.      * std-t elvből nem használjuk bevezető kurzusban, így ez a konstrukció csak
  237.      * az argfüggő névfeloldás miatt fordul le (B&L könyv 185. o. teteje) ám itt
  238.      * nem az a lényeg, hanem, hogy a cout ostream osztálybeli, így abban az
  239.      * osztályban kéne módosítani, hogy tudjon kiírni LZWBinFa
  240.      * osztálybelieket... e helyett a globális << operátort terheljük túl, a
  241.      * kiFile << binFa azt jelenti, hogy - tagfüggvényként:
  242.      * kiFile.operator<<(binFa) de ehhez a kiFile valamilyen std::ostream stream
  243.      * osztály forrásába kellene beleírni ezt a tagfüggvényt, amely ismeri a mi
  244.      * LZW binfánkat... - globális függvényként: operator<<(kiFile, binFa) és
  245.      * pont ez látszik a következő sorban:
  246.      */
  247.     friend std::ostream & operator <<(std::ostream & os, LZWBinFa & bf)
  248.     {
  249.         bf.kiir(os);
  250.         return os;
  251.     }
  252.  
  253.     /*
  254.      ===================================================================================================================
  255.      ===================================================================================================================
  256.      */
  257.     void    kiir(std::ostream & os)     { melyseg = 0; kiir(&gyoker, os); }
  258.  
  259. /*
  260.  -----------------------------------------------------------------------------------------------------------------------
  261.  -----------------------------------------------------------------------------------------------------------------------
  262.  */
  263. private:
  264.     class   Csomopont
  265.     {
  266.     public:
  267.  
  268.         /*
  269.          * A paraméter nélküli konstruktor az elepértelmezett '/' "gyökér-betűvel"
  270.          * hozza létre a csomópontot, ilyet hívunk a fából, aki tagként tartalmazza
  271.          * a gyökeret. Máskülönben, ha valami betűvel hívjuk, akkor azt teszi a
  272.          * "betu" tagba, a két gyermekre mutató mutatót pedig nullra állítjuk,
  273.          * C++-ban a 0 is megteszi.
  274.          */
  275.         Csomopont (char b = '/')
  276.         :
  277.         betu(b),
  278.         balNulla(0),
  279.         jobbEgy(0)
  280.         { };
  281.         ~Csomopont()
  282.         { };
  283.  
  284.         /*
  285.          ===============================================================================================================
  286.             Aktuális csomópont, mondd meg nékem, ki a bal oldali gyermeked ;
  287.             (a C verzió logikájával műxik ez is: ha nincs, akkor a null megy vissza)
  288.          ===============================================================================================================
  289.          */
  290.         Csomopont *nullasGyermek() const
  291.         {
  292.             return balNulla;
  293.         }
  294.  
  295.         /*
  296.          ===============================================================================================================
  297.             Aktuális csomópon,t mondd meg nékem, ki a jobb oldali gyermeked?
  298.          ===============================================================================================================
  299.          */
  300.         Csomopont *egyesGyermek() const
  301.         {
  302.             return jobbEgy;
  303.         }
  304.  
  305.         /*
  306.          ===============================================================================================================
  307.             Aktuális csomópont, ímhol legyen a "gy" mutatta csomópont a bal oldali gyereked!
  308.          ===============================================================================================================
  309.          */
  310.         void    ujNullasGyermek(Csomopont *gy)  { balNulla = gy; }
  311.  
  312.         /*
  313.          ===============================================================================================================
  314.             Aktuális csomópont, ímhol legyen a "gy" mutatta csomópont a jobb oldali gyereked!
  315.          ===============================================================================================================
  316.          */
  317.         void    ujEgyesGyermek(Csomopont *gy)   { jobbEgy = gy; }
  318.  
  319.         /*
  320.          ===============================================================================================================
  321.             Aktuális csomópont: Te milyen betűt hordozol? ;
  322.             (a const kulcsszóval jelezzük, hogy nem bántjuk a példányt)
  323.          ===============================================================================================================
  324.          */
  325.         char getBetu() const
  326.         {
  327.             return betu;
  328.         }
  329.  
  330.     private:
  331.  
  332.         /*
  333.          * friend class LZWBinFa;
  334.          * /* mert ebben a valtozatban az LZWBinFa metódusai nem közvetlenül ;
  335.          * a Csomopont tagjaival dolgoznak, hanem beállító/lekérdező üzenetekkel
  336.          * érik el azokat ;
  337.          * Milyen betűt hordoz a csomópont
  338.          */
  339.         char        betu;
  340.  
  341.         /*
  342.          * Melyik másik csomópont a bal oldali gyermeke? (a C változatból "örökölt"
  343.          * logika: ;
  344.          * ha hincs ilyen csermek, akkor balNulla == null) igaz
  345.          */
  346.         Csomopont   *balNulla;
  347.         Csomopont   *jobbEgy;
  348.  
  349.         /*
  350.          * nem másolható a csomópont (ökörszabály: ha van valamilye a szabad
  351.          * tárban, ;
  352.          * letiltjuk a másoló konstruktort, meg a másoló értékadást)
  353.          */
  354.         Csomopont (const Csomopont &);
  355.         Csomopont &operator =(const Csomopont &);
  356.     };
  357.  
  358.     /* Mindig a fa "LZW algoritmus logikája szerinti aktuális" csomópontjára mutat */
  359.     Csomopont           *fa;
  360.  
  361.     /* technikai */
  362.     int                 melyseg, atlagosszeg, atlagdb;
  363.     double              szorasosszeg;
  364.  
  365.     /* szokásosan: nocopyable */
  366.     LZWBinFa(const LZWBinFa &);
  367.     LZWBinFa &operator  =(const LZWBinFa &);
  368.  
  369.     /*-
  370.      ==-=================================================================================================================
  371.        - Kiírja a csomópontot az os csatornára. A rekurzió kapcsán lásd a korábbi K&R-es utalást...
  372.      ==-=================================================================================================================
  373.      */
  374.     void kiir(Csomopont * elem, std::ostream & os)
  375.     {
  376.  
  377.         /* Nem létező csomóponttal nem foglalkozunk... azaz ez a rekurzió leállítása */
  378.         if(elem != NULL)
  379.         {
  380.             ++melyseg;
  381.             kiir(elem->egyesGyermek(), os);
  382.  
  383.             /*
  384.              * ez a postorder bejáráshoz képest ;
  385.              * 1-el nagyobb mélység, ezért -1
  386.              */
  387.             for(int i = 0; i < melyseg; ++i) os << "---";
  388.             os << elem->getBetu() << "(" << melyseg - 1 << ")" << std::endl;
  389.             kiir(elem->nullasGyermek(), os);
  390.             --melyseg;
  391.         }
  392.     }
  393.  
  394.     /*
  395.      ===================================================================================================================
  396.      ===================================================================================================================
  397.      */
  398.     void szabadit(Csomopont *elem)
  399.     {
  400.  
  401.         /* Nem létező csomóponttal nem foglalkozunk... azaz ez a rekurzió leállítása */
  402.         if(elem != NULL)
  403.         {
  404.             szabadit(elem->egyesGyermek());
  405.             szabadit(elem->nullasGyermek());
  406.  
  407.             /*
  408.              * ha a csomópont mindkét gyermekét felszabadítottuk ;
  409.              * azután szabadítjuk magát a csomópontot:
  410.              */
  411.             delete elem;
  412.         }
  413.     }
  414.  
  415. /*
  416.  -----------------------------------------------------------------------------------------------------------------------
  417.  -----------------------------------------------------------------------------------------------------------------------
  418.  */
  419. protected:  /* ha esetleg egyszer majd kiterjesztjük az osztályt, mert */
  420.     /*
  421.      * akarunk benne valami újdonságot csinálni, vagy meglévő tevékenységet
  422.      * máshogy... stb. ;
  423.      * akkor ezek látszanak majd a gyerek osztályban is ;
  424.      * A fában tagként benne van egy csomópont, ez erősen ki van tüntetve, Ő a
  425.      * gyökér:
  426.      */
  427.     Csomopont   gyoker;
  428.     int         maxMelyseg;
  429.     double      atlag, szoras;
  430.  
  431.     void        rmelyseg(Csomopont *elem);
  432.     void        ratlag(Csomopont *elem);
  433.     void        rszoras(Csomopont *elem);
  434. };
  435.  
  436. /*
  437.  =======================================================================================================================
  438.     Néhány függvényt az osztálydefiníció után definiálunk, hogy lássunk ilyet is ... :) ;
  439.     Nem erőltetjük viszont a külön fájlba szedést, mert a sablonosztályosított tovább ;
  440.     fejlesztésben az linkelési gondot okozna, de ez a téma már kivezet a laborteljesítés ;
  441.     szükséges feladatából: http://progpater.blog.hu/2011/04/12/imadni_fogjak_a_c_t_egy_emberkent_tiszta_szivbol_3 ;
  442.     Egyébként a melyseg, atlag és szoras fgv.-ek a kiir fgv.-el teljesen egy kaptafa.
  443.  =======================================================================================================================
  444.  */
  445. int LZWBinFa::getMelyseg(void)
  446. {
  447.     melyseg = maxMelyseg = 0;   //változók resetelése
  448.     rmelyseg(&gyoker);          //számítás
  449.     return maxMelyseg - 1;
  450. }
  451.  
  452. /*
  453.  =======================================================================================================================
  454.  =======================================================================================================================
  455.  */
  456. double LZWBinFa::getAtlag(void)
  457. {
  458.     melyseg = atlagosszeg = atlagdb = 0;
  459.     ratlag(&gyoker);
  460.     atlag = ((double) atlagosszeg) / atlagdb;
  461.     return atlag;
  462. }
  463.  
  464. /*
  465.  =======================================================================================================================
  466.  =======================================================================================================================
  467.  */
  468. double LZWBinFa::getSzoras(void)
  469. {
  470.     atlag = getAtlag();
  471.     szorasosszeg = 0.0;
  472.     melyseg = atlagdb = 0;
  473.  
  474.     rszoras(&gyoker);
  475.  
  476.     if(atlagdb - 1 > 0)
  477.         szoras = std::sqrt(szorasosszeg / (atlagdb - 1));
  478.     else
  479.         szoras = std::sqrt(szorasosszeg);
  480.  
  481.     return szoras;
  482. }
  483.  
  484. /*
  485.  =======================================================================================================================
  486.  =======================================================================================================================
  487.  */
  488. void LZWBinFa::rmelyseg(Csomopont *elem)
  489. {
  490.     if(elem != NULL)
  491.     {
  492.         ++melyseg;  //rekurzió mieatt beljebb lépünk
  493.         if(melyseg > maxMelyseg) maxMelyseg = melyseg;
  494.         rmelyseg(elem->egyesGyermek());
  495.  
  496.         /*
  497.          * ez a postorder bejáráshoz képest ;
  498.          * 1-el nagyobb mélység, ezért -1
  499.          */
  500.         rmelyseg(elem->nullasGyermek());
  501.         --melyseg;  //majd visszalépünk a rekurzív hívás után
  502.     }
  503. }
  504.  
  505. /*
  506.  =======================================================================================================================
  507.  =======================================================================================================================
  508.  */
  509. void LZWBinFa::ratlag(Csomopont *elem)
  510. {
  511.     if(elem != NULL)
  512.     {
  513.         ++melyseg;
  514.         ratlag(elem->egyesGyermek());
  515.         ratlag(elem->nullasGyermek());
  516.         --melyseg;
  517.         if(elem->egyesGyermek() == NULL && elem->nullasGyermek() == NULL)
  518.         {
  519.             ++atlagdb;
  520.             atlagosszeg += melyseg;
  521.         }
  522.     }
  523. }
  524.  
  525. /*
  526.  =======================================================================================================================
  527.  =======================================================================================================================
  528.  */
  529. void LZWBinFa::rszoras(Csomopont *elem)
  530. {
  531.     if(elem != NULL)
  532.     {
  533.         ++melyseg;
  534.         rszoras(elem->egyesGyermek());
  535.         rszoras(elem->nullasGyermek());
  536.         --melyseg;
  537.         if(elem->egyesGyermek() == NULL && elem->nullasGyermek() == NULL)
  538.         {
  539.             ++atlagdb;
  540.             szorasosszeg += ((melyseg - atlag) * (melyseg - atlag));   
  541.             /*  szórás számítása:
  542.              *  1. Kiszámítjuk az adatok számtani közepét.
  543.              *  2. Kiszámítjuk az adatok eltérését a számtani középtől (adat - számtani közép)
  544.              *  3. Vesszük ezeknek az eltéréseknek a négyzetét.
  545.              *  4. Kiszámítjuk ezeknek az "eltérés négyzeteknek" a számtani közepét.
  546.              *  5. Végül ebből négyzetgyököt vonunk.
  547.              */
  548.         }
  549.     }
  550. }
  551.  
  552. /*
  553.  =======================================================================================================================
  554.     teszt pl.: http://progpater.blog.hu/2011/03/05/labormeres_otthon_avagy_hogyan_dolgozok_fel_egy_pedat ;
  555.     [norbi@sgu ~]$ echo "01111001001001000111"|./z3a2 ;
  556.     ------------1(3)
  557.     ---------1(2)
  558.     ------1(1)
  559.     ---------0(2)
  560.     ------------0(3)
  561.     ---------------0(4)
  562.     ---/(0)
  563.     ---------1(2)
  564.     ------0(1)
  565.     ---------0(2)
  566.     depth = 4 ;
  567.     mean = 2.75 ;
  568.     var = 0.957427 ;
  569.     a laborvédéshez majd ezt a tesztelést használjuk: ;
  570.     http:// ;
  571.     Ez volt eddig a main, de most komplexebb kell, mert explicite bejövő, kimenő fájlokkal kell dolgozni int main
  572.     () { char b;
  573.     LZWBinFa binFa;
  574.     while (std::cin >> b) { binFa << b;
  575.     } //std::cout << binFa.kiir ();
  576.     // így rajzolt ki a fát a korábbi verziókban de, hogy izgalmasabb legyen // a példa, azaz ki lehessen tolni az
  577.     LZWBinFa-t kimeneti csatornára: std::cout << binFa;
  578.     // ehhez kell a globális operator<< túlterhelése, lásd fentebb std::cout << "depth = " << binFa.getMelyseg ()
  579.     << std::endl;
  580.     std::cout << "mean = " << binFa.getAtlag () << std::endl;
  581.     std::cout << "var = " << binFa.getSzoras () << std::endl;
  582.     binFa.szabadit ();
  583.     return 0;
  584.     } ;
  585.     A parancssor arg. kezelést egyszerűen bedolgozzuk a 2. hullám kapcsolódó feladatából:
  586.     http://progpater.blog.hu/2011/03/12/hey_mikey_he_likes_it_ready_for_more_3 de mivel nekünk sokkal egyszerűbb is
  587.     elég, alig hagyunk meg belőle valamit...
  588.  =======================================================================================================================
  589.  */
  590. void usage(void)
  591. {
  592.     std::cout << "Usage: lzwtree in_file -<switch> out_file" << std::endl << "Switches: -o: no draw; -d: draw; -p:print to screen (no draw)";
  593. }
  594.  
  595. /*
  596.  =======================================================================================================================
  597.  =======================================================================================================================
  598.  */
  599. int main(int argc, char *argv[])
  600. {
  601.    
  602.     /*
  603.      * http://progpater.blog.hu/2011/03/12/hey_mikey_he_likes_it_ready_for_more_3 ;
  604.      * alapján a parancssor argok ottani elegáns feldolgozásából kb. ennyi marad: ;
  605.      * "*((*++argv)+1)"... ;
  606.      * a kiírás szerint ./lzwtree in_file -o out_file alakra kell mennie, ez 4 db
  607.      * arg:
  608.      */
  609.  
  610.      /*Kirajzoljuk-e a fát?*/
  611.      bool drawMe = false;
  612.  
  613.     if(argc != 4)
  614.     {
  615.  
  616.         /* ha nem annyit kapott a program, akkor felhomályosítjuk erről a júzetr: */
  617.         usage();
  618.  
  619.         /* és jelezzük az operációs rendszer felé, hogy valami gáz volt... */
  620.         return -1;
  621.     }
  622.  
  623.     /*~~~~~~~~~~~~~~~~~~~~~~*/
  624.     /* "Megjegyezzük" a bemenő fájl nevét */
  625.     char    *inFile = *++argv;
  626.     /*~~~~~~~~~~~~~~~~~~~~~~*/
  627.  
  628.     /* a -o kapcsoló jön? */
  629.     char oSwitch = *((*++argv) + 1);
  630.     if(oSwitch != 'o' && oSwitch != 'd' )
  631.     {
  632.         std::cout << oSwitch;
  633.         usage();
  634.         return -2;
  635.     }
  636.  
  637.     if (oSwitch == 'd' )
  638.         drawMe = true;
  639.  
  640.     /* ha igen, akkor az 5. előadásból kimásoljuk a fájlkezelés C++ változatát: */
  641.     std::fstream beFile(inFile, std::ios_base::in);
  642.  
  643.     /*
  644.      * fejlesztgetjük a forrást:
  645.      * http://progpater.blog.hu/2011/04/17/a_tizedik_tizenegyedik_labor
  646.      */
  647.     if(!beFile)
  648.     {
  649.         std::cout << inFile << " nem letezik..." << std::endl;
  650.         usage();
  651.         return -3;
  652.     }
  653.  
  654.     std::fstream kiFile(*++argv, std::ios_base::out);
  655.  
  656.     /*~~~~~~~~~~~~~~~~~~*/
  657.     unsigned char   b;      /* ide olvassik majd a bejövő fájl bájtjait */
  658.     LZWBinFa        binFa;  /* s nyomjuk majd be az LZW fa objektumunkba */
  659.     /*~~~~~~~~~~~~~~~~~~*/
  660.  
  661.     /*
  662.      * a bemenetet binárisan olvassuk, de a kimenő fájlt már karakteresen írjuk,
  663.      * hogy meg tudjuk ;
  664.      * majd nézni... :) l. az említett 5. ea. C -> C++ gyökkettes átírási
  665.      * példáit
  666.      */
  667.     while(beFile.read((char *) &b, sizeof(unsigned char)))
  668.         if(b == 0x0a) break;
  669.  
  670.     /*~~~~~~~~~~~~~~~~~~~~~~~*/
  671.     bool    kommentben = false;
  672.     /*~~~~~~~~~~~~~~~~~~~~~~~*/
  673.  
  674.     while(beFile.read((char *) &b, sizeof(unsigned char)))
  675.     {
  676.         if(b == 0x3e)
  677.         {   /* > karakter */
  678.             kommentben = true;
  679.             continue;
  680.         }
  681.  
  682.         if(b == 0x0a)
  683.         {   /* újsor */
  684.             kommentben = false;
  685.             continue;
  686.         }
  687.  
  688.         if(kommentben) continue;
  689.         if(b == 0x4e)   /* N betű */
  690.             continue;
  691.  
  692.         /*
  693.          * egyszerűen a korábbi d.c kódját bemásoljuk ;
  694.          * laboron többször lerajzoltuk ezt a bit-tologatást: ;
  695.          * a b-ben lévő bájt bitjeit egyenként megnézzük
  696.          */
  697.         for(int i = 0; i < 8; ++i)
  698.         {
  699.  
  700.             /*
  701.              * maszkolunk eddig..., most már simán írjuk az if fejébe a legmagasabb
  702.              * helyiértékű bit vizsgálatát ;
  703.              * csupa 0 lesz benne a végén pedig a vizsgált 0 vagy 1, az if megmondja
  704.              * melyik:
  705.              */
  706.             if(b & 0x80)
  707.  
  708.                 /* ha a vizsgált bit 1, akkor az '1' betűt nyomjuk az LZW fa objektumunkba */
  709.                 binFa << '1';
  710.             else
  711.                 /* különben meg a '0' betűt: */
  712.                 binFa << '0';
  713.             b <<= 1;
  714.         }
  715.     }
  716.  
  717.     /*
  718.      * std::cout << binFa.kiir ();
  719.      * // így rajzolt ki a fát a korábbi verziókban de, hogy izgalmasabb legyen ;
  720.      * a példa, azaz ki lehessen tolni az LZWBinFa-t kimeneti csatornára:
  721.      */
  722.     if (drawMe == true)
  723.         kiFile << binFa;    /* ehhez kell a globális operator<< túlterhelése, lásd fentebb */
  724.  
  725.     /*
  726.      * (jó ez az OO, mert mi ugye nem igazán erre gondoltunk, amikor írtuk, mégis
  727.      * megy, hurrá)
  728.      */
  729.     kiFile << "depth = " << binFa.getMelyseg() << std::endl;
  730.     kiFile << "mean = " << binFa.getAtlag() << std::endl;
  731.     kiFile << "var = " << binFa.getSzoras() << std::endl;
  732.  
  733.     kiFile.close();
  734.     beFile.close();
  735.  
  736.     return 0;
  737. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement