Advertisement
Guest User

Humángenom

a guest
Nov 4th, 2013
321
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 17.17 KB | None | 0 0
  1. // z3a5.cpp
  2. //
  3. // Együtt támadjuk meg: http://progpater.blog.hu/2011/04/14/egyutt_tamadjuk_meg
  4. // LZW fa építő 3. C++ átirata a C valtozatbol (+mélység, atlag és szórás)
  5. // Programozó Páternoszter
  6. //
  7. // Copyright (C) 2011, Bátfai Norbert, nbatfai@inf.unideb.hu, nbatfai@gmail.com
  8. //
  9. // This program is free software: you can redistribute it and/or modify
  10. // it under the terms of the GNU General Public License as published by
  11. // the Free Software Foundation, either version 3 of the License, or
  12. // (at yout option) any later version.
  13. //
  14. // This program is distributed in the hope that it will be useful,
  15. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17. // GNU General Public License for more details.
  18. //
  19. // You should have received a copy of the GNU General Public License
  20. // along with this program.  If not, see <http://www.gnu.org/licenses/>.
  21. //
  22. // Ez a program szabad szoftver; terjeszthetõ illetve módosítható a
  23. // Free Software Foundation által kiadott GNU General Public License
  24. // dokumentumában leírtak; akár a licenc 3-as, akár (tetszõleges) késõbbi
  25. // változata szerint.
  26. //
  27. // Ez a program abban a reményben kerül közreadásra, hogy hasznos lesz,
  28. // de minden egyéb GARANCIA NÉLKÜL, az ELADHATÓSÁGRA vagy VALAMELY CÉLRA
  29. // VALÓ ALKALMAZHATÓSÁGRA való származtatott garanciát is beleértve.
  30. // További részleteket a GNU General Public License tartalmaz.
  31. //
  32. // A felhasználónak a programmal együtt meg kell kapnia a GNU General
  33. // Public License egy példányát; ha mégsem kapta meg, akkor
  34. // tekintse meg a <http://www.gnu.org/licenses/> oldalon.
  35. //
  36. //
  37. // Version history:
  38. //
  39. // 0.0.1,       http://progpater.blog.hu/2011/02/19/gyonyor_a_tomor
  40. // 0.0.2,       csomópontok mutatóinak nullázása (nem fejtette meg senki :)
  41. // 0.0.3,       http://progpater.blog.hu/2011/03/05/labormeres_otthon_avagy_hogyan_dolgozok_fel_egy_pedat
  42. // 0.0.4,       z.cpp: a C verzióból svn: bevezetes/C/ziv/z.c átírjuk C++-ra
  43. //              http://progpater.blog.hu/2011/03/31/imadni_fogjatok_a_c_t_egy_emberkent_tiszta_szivbol
  44. // 0.0.5,       z2.cpp: az fgv(*mut)-ok helyett fgv(&ref)
  45. // 0.0.6,       z3.cpp: Csomopont beágyazva
  46. //              http://progpater.blog.hu/2011/04/01/imadni_fogjak_a_c_t_egy_emberkent_tiszta_szivbol_2
  47. // 0.0.6.1      z3a2.c: LZWBinFa már nem barátja a Csomopont-nak, mert annak tagjait nem használja direktben
  48. // 0.0.6.2      Kis kommentezést teszünk bele 1. lépésként (hogy a kicsit lemaradt hallgatóknak is
  49. //              könnyebb legyen, jól megtűzdeljük további olvasmányokkal)
  50. //              http://progpater.blog.hu/2011/04/14/egyutt_tamadjuk_meg
  51. //              (majd a 2. lépésben "beletesszük a d.c-t", majd s 3. lépésben a parancssorsor argok feldolgozását)
  52. // 0.0.6.3      z3a2.c: Fejlesztgetjük a forrást: http://progpater.blog.hu/2011/04/17/a_tizedik_tizenegyedik_labor
  53. // 0.0.6.4      SVN-beli, http://www.inf.unideb.hu/~nbatfai/p1/forrasok-SVN/bevezetes/vedes/
  54. // 0.0.6.5      2012.03.20, z3a4.cpp: N betűk (hiányok), sorvégek, vezető komment figyelmen kívül: http://progpater.blog.hu/2012/03/20/a_vedes_elokeszitese
  55. // 0.0.6.6      z3a5.cpp: mamenyaka kolléga észrevételére a több komment sor figyelmen kívül hagyása
  56. //
  57.  
  58.  
  59. import java.io.*;
  60.  
  61. /* Az LZWBinFa osztályban absztraháljuk az LZW algoritmus bináris fa építését. Az osztály
  62.  definíciójába beágyazzuk a fa egy csomópontjának az absztrakt jellemzését, ez lesz a
  63.  beágyazott Csomopont osztály. Miért ágyazzuk be? Mert külön nem szánunk neki szerepet, ezzel
  64.  is jelezzük, hogy csak a fa részeként számiolunk vele.*/
  65.  
  66. class LZWBinFa
  67. {               /* Szemben a bináris keresőfánkkal (BinFa osztály)
  68.                    http://progpater.blog.hu/2011/04/12/imadni_fogjak_a_c_t_egy_emberkent_tiszta_szivbol_3
  69.                    itt (LZWBinFa osztály) a fa gyökere nem pointer, hanem a '/' betüt tartalmazó objektum,
  70.                    lásd majd a védett tagok között lent: Csomopont gyoker;
  71.                    A fa viszont már pointer, mindig az épülő LZW-fánk azon csomópontjára mutat, amit az
  72.                    input feldolgozása során az LZW algoritmus logikája diktál:
  73.                    http://progpater.blog.hu/2011/02/19/gyonyor_a_tomor
  74.                    Ez a konstruktor annyit csinál, hogy a fa mutatót ráállítja a gyökérre. (Mert ugye
  75.                    labopon, blogon, előadásban tisztáztuk, hogy a tartalmazott tagok, most "Csomopont gyoker"
  76.                    konstruktora előbb lefut, mint a tagot tartalmazó LZWBinFa osztály konstruktora, éppen a
  77.                    következő, azaz a fa=gyoker OK.)
  78.                  */
  79.   public LZWBinFa ()
  80.   {
  81.     gyoker = new Csomopont ('/');
  82.     fa = gyoker;
  83.   }
  84.  
  85.   public void beolvas (char b)
  86.   {
  87.     // Mit kell betenni éppen, '0'-t?
  88.     if (b == '0')
  89.       {
  90.     /* Van '0'-s gyermeke az aktuális csomópontnak?
  91.        megkérdezzük Tőle, a "fa" mutató éppen reá mutat */
  92.     if (fa.nullasGyermek () == null)    // ha nincs, hát akkor csinálunk
  93.       {
  94.         // elkészítjük, azaz páldányosítunk a '0' betű akt. parammal
  95.         Csomopont uj = new Csomopont ('0');
  96.         // az aktuális csomópontnak, ahol állunk azt üzenjük, hogy
  97.         // jegyezze már be magának, hogy nullás gyereke mostantól van
  98.         // küldjük is Neki a gyerek címét:
  99.         fa.ujnullasGyermek (uj);
  100.         // és visszaállunk a gyökérre (mert ezt diktálja az alg.)
  101.         fa = gyoker;
  102.       }
  103.     else            // ha van, arra rálépünk
  104.       {
  105.         // azaz a "fa" pointer már majd a szóban forgó gyermekre mutat:
  106.         fa = fa.nullasGyermek ();
  107.       }
  108.       }
  109.     // Mit kell betenni éppen, vagy '1'-et?
  110.     else
  111.       {
  112.     if (fa.egyesGyermek () == null)
  113.       {
  114.         Csomopont uj = new Csomopont ('1');
  115.         fa.ujEgyesGyermek (uj);
  116.         fa = gyoker;
  117.       }
  118.     else
  119.       {
  120.         fa = fa.egyesGyermek ();
  121.       }
  122.       }
  123.   }
  124.   /* A bejárással kapcsolatos függvényeink (túlterhelt kiir-ók, atlag, ratlag stb.) rekurzívak,
  125.      tk. a rekurzív 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)
  126.  
  127.      (Ha a rekurzív függvénnyel általában gondod van => K&R könyv megfelelő része: a 3. ea. izometrikus
  128.      részében ezt "letáncoltuk" :) és külön idéztük a K&R álláspontját :)
  129.    */
  130.  
  131.   /* A változatosság kedvéért ezeket az osztálydefiníció (class LZWBinFa {...};) után definiáljuk,
  132.      hogy kénytelen légy az LZWBinFa és a :: hatókör operátorral minősítve definiálni :) l. lentebb */
  133.   public int getMelyseg ()
  134.   {
  135.     melyseg = maxMelyseg = 0;
  136.     rmelyseg (gyoker);
  137.     return maxMelyseg - 1;
  138.   }
  139.   public double getSzoras ()
  140.   {
  141.     atlag = getAtlag ();
  142.     szorasosszeg = 0.0;
  143.     melyseg = atlagdb = 0;
  144.  
  145.     rszoras (gyoker);
  146.  
  147.     if (atlagdb - 1 > 0)
  148.       szoras = Math.sqrt (szorasosszeg / (atlagdb - 1));
  149.     else
  150.       szoras = Math.sqrt (szorasosszeg);
  151.  
  152.     return szoras;
  153.   }
  154.   public double getAtlag ()
  155.   {
  156.     melyseg = atlagosszeg = atlagdb = 0;
  157.     ratlag (gyoker);
  158.     atlag = ((double) atlagosszeg) / atlagdb;
  159.     return atlag;
  160.   }
  161.  
  162.  
  163.   /* Vágyunk, hogy a felépített LZW fát ki tudjuk nyomni ilyenformán: std::cout << binFa;
  164.      de mivel a << operátor is a sztenderd névtérben van, de a using namespace std-t elvből
  165.      nem használjuk bevezető kurzusban, így ez a konstrukció csak az argfüggő névfeloldás miatt
  166.      fordul le (B&L könyv 185. o. teteje) ám itt nem az a lényeg, hanem, hogy a cout ostream
  167.      osztálybeli, így abban az osztályban kéne módosítani, hogy tudjon kiírni LZWBinFa osztálybelieket...
  168.      e helyett a globális << operátort terheljük túl, */
  169.   private class Csomopont
  170.   {
  171.     /* A paraméter nélküli konstruktor az elepértelmezett '/' "gyökér-betűvel" hozza
  172.        létre a csomópontot, ilyet hívunk a fából, aki tagként tartalmazza a gyökeret.
  173.        Máskülönben, ha valami betűvel hívjuk, akkor azt teszi a "betu" tagba, a két
  174.        gyermekre mutató mutatót pedig nullra állítjuk, C++-ban a 0 is megteszi. */
  175.     public Csomopont (char b)
  176.     {
  177.       betu = b;
  178.     };
  179.  
  180.     // Aktuális csomópont, mondd meg nékem, ki a bal oldali gyermeked
  181.     // (a C verzió logikájával műxik ez is: ha nincs, akkor a null megy vissza)
  182.     public Csomopont nullasGyermek ()
  183.     {
  184.       return balnulla;
  185.     }
  186.     // Aktuális csomópon,t mondd meg nékem, ki a jobb oldali gyermeked?
  187.     public Csomopont egyesGyermek ()
  188.     {
  189.       return jobbEgy;
  190.     }
  191.     // Aktuális csomópont, ímhol legyen a "gy" mutatta csomópont a bal oldali gyereked!
  192.     public void ujnullasGyermek (Csomopont gy)
  193.     {
  194.       balnulla = gy;
  195.     }
  196.     // Aktuális csomópont, ímhol legyen a "gy" mutatta csomópont a jobb oldali gyereked!
  197.     public void ujEgyesGyermek (Csomopont gy)
  198.     {
  199.       jobbEgy = gy;
  200.     }
  201.     // Aktuális csomópont: Te milyen betűt hordozol?
  202.     // (a const kulcsszóval jelezzük, hogy nem bántjuk a példányt)
  203.     public char getBetu ()
  204.     {
  205.       return betu;
  206.     }
  207.  
  208.     // friend class LZWBinFa; /* mert ebben a valtozatban az LZWBinFa metódusai nem közvetlenül
  209.     // a Csomopont tagjaival dolgoznak, hanem beállító/lekérdező üzenetekkel érik el azokat */
  210.  
  211.     // Milyen betűt hordoz a csomópont
  212.     private char betu;
  213.     // Melyik másik csomópont a bal oldali gyermeke? (a C változatból "örökölt" logika:
  214.     // ha hincs ilyen csermek, akkor balnulla == null) igaz
  215.     private Csomopont balnulla;
  216.     private Csomopont jobbEgy;
  217.   };
  218.  
  219.   /* Mindig a fa "LZW algoritmus logikája szerinti aktuális" csomópontjára mutat */
  220.   Csomopont fa;
  221.   // technikai
  222.   private int melyseg, atlagosszeg, atlagdb;
  223.   private double szorasosszeg;
  224.   /* Kiírja a csomópontot az os csatornára. A rekurzió kapcsán lásd a korábbi K&R-es utalást... */
  225.   public void kiir (Csomopont elem, FileWriter file) throws IOException
  226.   {
  227.  
  228.     // Nem létező csomóponttal nem foglalkozunk... azaz ez a rekurzió leállítása
  229.     if (elem != null)
  230.       {
  231.     ++melyseg;
  232.     kiir (elem.egyesGyermek (), file);
  233.  
  234.     // ez a postorder bejáráshoz képest
  235.     // 1-el nagyobb mélység, ezért -1
  236.     for (int i = 0; i < melyseg; ++i)
  237.       file.write ("---");
  238.     file.write (elem.getBetu () + "(" + (melyseg - 1) + ")" + "\n");
  239.     kiir (elem.nullasGyermek (), file);
  240.     --melyseg;
  241.  
  242.       }
  243.   }
  244.  
  245.   // ha esetleg egyszer majd kiterjesztjük az osztályt, mert
  246. // akarunk benne valami újdonságot csinálni, vagy meglévő tevékenységet máshogy... stb.
  247. // akkor ezek látszanak majd a gyerek osztályban is
  248.  
  249.   /* A fában tagként benne van egy csomópont, ez erősen ki van tüntetve, Ő a gyökér: */
  250.   public Csomopont gyoker;
  251.   protected int maxMelyseg;
  252.   protected double atlag, szoras;
  253.  
  254.   protected void rmelyseg (Csomopont elem)
  255.   {
  256.     if (elem != null)
  257.       {
  258.     ++melyseg;
  259.     if (melyseg > maxMelyseg)
  260.       maxMelyseg = melyseg;
  261.     rmelyseg (elem.egyesGyermek ());
  262.     // ez a postorder bejáráshoz képest
  263.     // 1-el nagyobb mélység, ezért -1
  264.     rmelyseg (elem.nullasGyermek ());
  265.     --melyseg;
  266.       }
  267.   }
  268.   protected void ratlag (Csomopont elem)
  269.   {
  270.     if (elem != null)
  271.       {
  272.     ++melyseg;
  273.     ratlag (elem.egyesGyermek ());
  274.     ratlag (elem.nullasGyermek ());
  275.     --melyseg;
  276.     if (elem.egyesGyermek () == null && elem.nullasGyermek () == null)
  277.       {
  278.         ++atlagdb;
  279.         atlagosszeg += melyseg;
  280.       }
  281.       }
  282.   }
  283.   protected void rszoras (Csomopont elem)
  284.   {
  285.     if (elem != null)
  286.       {
  287.     ++melyseg;
  288.     rszoras (elem.egyesGyermek ());
  289.     rszoras (elem.nullasGyermek ());
  290.     --melyseg;
  291.     if (elem.egyesGyermek () == null && elem.nullasGyermek () == null)
  292.       {
  293.         ++atlagdb;
  294.         szorasosszeg += ((melyseg - atlag) * (melyseg - atlag));
  295.       }
  296.       }
  297.   }
  298.  
  299. }
  300.  
  301. // Néhány függvényt az osztálydefiníció után definiálunk, hogy lássunk ilyet is ... :)
  302. // Nem erőltetjük viszont a külön fájlba szedést, mert a sablonosztályosított tovább
  303. // fejlesztésben az linkelési gondot okozna, de ez a téma már kivezet a laborteljesítés
  304. // szükséges feladatából: http://progpater.blog.hu/2011/04/12/imadni_fogjak_a_c_t_egy_emberkent_tiszta_szivbol_3
  305.  
  306. // Egyébként a melyseg, atlag és szoras fgv.-ek a kiir fgv.-el teljesen egy kaptafa.
  307. // teszt pl.: http://progpater.blog.hu/2011/03/05/labormeres_otthon_avagy_hogyan_dolgozok_fel_egy_pedat
  308. // [norbi@sgu ~]$ echo "01111001001001000111"|./z3a2
  309. // ------------1(3)
  310. // ---------1(2)
  311. // ------1(1)
  312. // ---------0(2)
  313. // ------------0(3)
  314. // ---------------0(4)
  315. // ---/(0)
  316. // ---------1(2)
  317. // ------0(1)
  318. // ---------0(2)
  319. // depth = 4
  320. // mean = 2.75
  321. // var = 0.957427
  322. // a laborvédéshez majd ezt a tesztelést használjuk:
  323. // http://
  324.  
  325. /* Ez volt eddig a main, de most komplexebb kell, mert explicite bejövő, kimenő fájlokkal kell dolgozni
  326. int
  327. main ()
  328. {
  329.     char b;
  330.     LZWBinFa binFa;
  331.  
  332.     while (std::cin >> b)
  333.     {
  334.         binFa << b;
  335.     }
  336.  
  337.     //std::cout << binFa.kiir (); // így rajzolt ki a fát a korábbi verziókban de, hogy izgalmasabb legyen
  338.     // a példa, azaz ki lehessen tolni az LZWBinFa-t kimeneti csatornára:
  339.  
  340.     std::cout << binFa; // ehhez kell a globális operator<< túlterhelése, lásd fentebb
  341.  
  342.     std::cout << "depth = " << binFa.getMelyseg () << std::endl;
  343.     std::cout << "mean = " << binFa.getAtlag () << std::endl;
  344.     std::cout << "var = " << binFa.getSzoras () << std::endl;
  345.  
  346.     binFa.szabadit ();
  347.  
  348.     return 0;
  349. }
  350. */
  351.  
  352. /* A parancssor arg. kezelést egyszerűen bedolgozzuk a 2. hullám kapcsolódó feladatából:
  353.  http://progpater.blog.hu/2011/03/12/hey_mikey_he_likes_it_ready_for_more_3
  354.  de mivel nekünk sokkal egyszerűbb is elég, alig hagyunk meg belőle valamit...
  355.  */
  356. public class Humangenom
  357. {
  358.   public static void usage ()
  359.   {
  360.     System.out.println ("Usage: lzwtree in_file out_file");
  361.   }
  362.  
  363.   public static void main (String args[])
  364.   {
  365.     // http://progpater.blog.hu/2011/03/12/hey_mikey_he_likes_it_ready_for_more_3
  366.     // alapján a parancssor argok ottani elegáns feldolgozásából kb. ennyi marad:
  367.     // "*((*++argv)+1)"...
  368.  
  369.     // a kiírás szerint ./lzwtree in_file -o out_file alakra kell mennie, ez 4 db arg:
  370.     if (args.length != 2)
  371.       {
  372.     // ha nem annyit kapott a program, akkor felhomályosítjuk erről a júzetr:
  373.     usage ();
  374.     // és jelezzük az operációs rendszer felé, hogy valami gáz volt...
  375.     return;
  376.       }
  377.  
  378.     // "Megjegyezzük" a bemenő fájl nevét
  379.     // a -o kapcsoló jön?
  380.  
  381.     FileReader beFile;
  382.     FileWriter kiFile;
  383.     // ha igen, akkor az 5. előadásból kimásoljuk a fájlkezelés C++ változatát:
  384.     char b;         // ide olvassik majd a bejövő fájl bájtjait
  385.     LZWBinFa binFa = new LZWBinFa ();   // s nyomjuk majd be az LZW fa objektumunkba
  386.     try
  387.     {
  388.       beFile = new FileReader (args[0]);
  389.       try
  390.       {
  391.     while (beFile.ready ())
  392.       {
  393.         b = (char) beFile.read ();
  394.         if (b == 0x0a)
  395.           break;
  396.       }
  397.       }
  398.       catch (IOException e)
  399.       {
  400.       }
  401.       boolean kommentben = false;
  402.       try
  403.       {
  404.     while (beFile.ready ())
  405.       {
  406.         b = (char) beFile.read ();
  407.         if (b == 0x3e)
  408.           {         // > karakter
  409.         kommentben = true;
  410.         continue;
  411.           }
  412.  
  413.         if (b == 0x0a)
  414.           {         // újsor
  415.         kommentben = false;
  416.         continue;
  417.           }
  418.  
  419.         if (kommentben)
  420.           continue;
  421.  
  422.         if (b == 0x4e)  // N betű
  423.           continue;
  424.  
  425.         // egyszerűen a korábbi d.c kódját bemásoljuk
  426.         // laboron többször lerajzoltuk ezt a bit-tologatást:
  427.         // a b-ben lévő bájt bitjeit egyenként megnézzük
  428.         int szo = (int) b;
  429.         for (int i = 0; i < 8; ++i)
  430.           {
  431.         // maszkolunk eddig..., most már simán írjuk az if fejébe a legmagasabb helyiértékű bit vizsgálatát
  432.         // csupa 0 lesz benne a végén pedig a vizsgált 0 vagy 1, az if megmondja melyik:
  433.         if ((int) (szo / Math.pow (2, 7 - i)) == 1)
  434.           {
  435.             // ha a vizsgált bit 1, akkor az '1' betűt nyomjuk az LZW fa objektumunkba
  436.             binFa.beolvas ('1');
  437.             szo -= Math.pow (2, 7 - i);
  438.           }
  439.         else
  440.           // különben meg a '0' betűt:
  441.           binFa.beolvas ('0');
  442.           }
  443.  
  444.       }
  445.       }
  446.       catch (IOException e)
  447.       {
  448.       }
  449.     }
  450.     catch (FileNotFoundException ex)
  451.     {
  452.       System.out.println (args[0] + " nem letezik");
  453.       return;
  454.     }
  455.  
  456.     // fejlesztgetjük a forrást: http://progpater.blog.hu/2011/04/17/a_tizedik_tizenegyedik_labor
  457.     try
  458.     {
  459.       kiFile = new FileWriter (args[1]);
  460.       // a bemenetet binárisan olvassuk, de a kimenő fájlt már karakteresen írjuk, hogy meg tudjuk
  461.       // majd nézni... :) l. az említett 5. ea. C . C++ gyökkettes átírási példáit
  462.  
  463.  
  464.       //std::cout << binFa.kiir (); // így rajzolt ki a fát a korábbi verziókban de, hogy izgalmasabb legyen
  465.       // a példa, azaz ki lehessen tolni az LZWBinFa-t kimeneti csatornára:
  466.       binFa.kiir (binFa.gyoker, kiFile);
  467.       // ehhez kell a globális operator<< túlterhelése, lásd fentebb
  468.       // (jó ez az OO, mert mi ugye nem igazán erre gondoltunk, amikor írtuk, mégis megy, hurrá)
  469.  
  470.       kiFile.write ("depth = " + binFa.getMelyseg () + "\n");
  471.       kiFile.write ("mean = " + binFa.getAtlag () + "\n");
  472.       kiFile.write ("var = " + binFa.getSzoras () + "\n");
  473.  
  474.       kiFile.close ();
  475.       beFile.close ();
  476.     }
  477.     catch (IOException ex)
  478.     {
  479.     }
  480.   }
  481. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement