HTML

Programozó Páternoszter

Ez a Programozó Páternoszter (PP) blogja, a programozásról szól. Aktualitása, hogy a Debreceni Egyetem Informatikai Kara Magasszintű programozási nyelvek 1-2, C++ esattanulmányok, Java esettanulmányok című kurzusainak blogja is egyben.

A vadászat

A Debreceni Egyetem Programozói Évkönyve: az UDPROG projekt. A szakmai fórumunk a Facebook-en. Az új előadások a prezin.
A régi előadások:
Prog1:
1. C bevezetés
2. C tárgyalás
3. C befejezés
4. C a gyakorlatban
5. C++ bevezetés
6. C++ tárgyalás
7. C++ befejezés
8. C++ a gyakorlatban
9. Java platform bevezetés
10. Kvantuminformatikai alg. bev.
Prog2:
1. Java bevezetés
2. Java tárgyalás
3. Java befejezés
4. Java a gyakorlatban
5. Software Engineering bev.
6. Java EE bevezetés
7. AspectJ bevezetés
8. BPMN-BPEL SOA programozás
9. C++ haladó
10. Tensorflow

Kövess engem!

Friss topikok

Linkblog

Imádni fogják a C++-t, egy emberként, tiszta szívből 4 (*)

2012.04.10. 15:43 nb

Ez a 6. (logikai) előadás posztja. Fő feladatunk a védés előkészítése után maga a védés. Aki már az április 9-i héten a laborján vállalja a z3a7.cpp forrás celebrálását, annak máris megvan a félév közepei védése, feltéve persze, hogy a celebráció sikeres. (Áprilisban letehető még az első védés, ez további 2 labort jelent, így összesen három alkalommal lehet védeni, de mielőbb próbálkozz, mert ha mindenki az utolsó alkalomra tolja, akkor nyilván lesz, akire nem fog sor kerülni... )

El lehet kezdeni közvetlenül magának a z3a7.cpp forrásnak a feldolgozását, a héten ezt (remélhetőleg hallgatói celebrációval) meg fogjuk tenni. Aki szeretne egy kis kronológiai emlékeztetőt a témáról, annak íme álljon itt egy:

  • a Tömör a gyönyörben kifejlesztettünk egy C struktúrás LZW (bináris) fa építőt
    (ebből a posztból kiadtunk újat is ebben a félévben: ez volt a Gyönyör a tömör újratöltve)
  • mélyebben megismerkedhettél a kóddal a Labormérés otthon, avagy hogyan dolgozok fel egy példát posztban, ugyanezt az ábrát (az algoritmus bevezetésekor) a félévben a laboron is elkészítettük, illetve az előadáson is tárgyaltuk.
  • amit jó (K&R) szokás szerint továbbfejlesztések során át elkezdtünk átteni C++-ba
    (erről még szólunk a heti laboron)
  • ITT JÖN EBBEN A RENDBEN A VÉDÉS
  • (ez viszont már a jövő lesz, mert itt már generikust is használunk majd, s el is szakadunk a humán genomtól a sima binárisfa kezelő felé)  a kezdő PolarGen és a saját Verem osztályod 12 változata után sikerrel veszed a "9-10" labort, ahol "sablonosítjuk a vermet", majd végül a BinFa osztályt is.

Mivel is motiválhatnám a hallgatóságot? Az április 9-i héten, laborközösségenként az első sikeres védőnek 10 trófeát, a másodiknak sikeres védőnek 7 trófeát ajánlok fel.

Jöjjön maga a kód, amit védésre/celebrálásra javaslok, de előtte az első lépés, hogy tudd futtatni és ugyanaz jöjjön ki ugyanarra az inputra, mint a védés előkészítésénél már teszteltük.

A Csomopont osztály

 

 

 

 

 

 

 

Az LZWBinFa osztály

 

 

 

 

 

 

 

 

 

 

 

 

 

  

és a kapcsolatuk

 z3a7.cpp

// z3a7.cpp
//
// Együtt támadjuk meg: http://progpater.blog.hu/2011/04/14/egyutt_tamadjuk_meg
// LZW fa építő 3. C++ átirata a C valtozatbol (+mélység, atlag és szórás)
// Programozó Páternoszter
//
// Copyright (C) 2011, 2012, Bátfai Norbert, nbatfai@inf.unideb.hu, nbatfai@gmail.com
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
// Ez a program szabad szoftver; terjeszthetõ illetve módosítható a
// Free Software Foundation által kiadott GNU General Public License
// dokumentumában leírtak; akár a licenc 3-as, akár (tetszõleges) késõbbi
// változata szerint.
//
// Ez a program abban a reményben kerül közreadásra, hogy hasznos lesz,
// de minden egyéb GARANCIA NÉLKÜL, az ELADHATÓSÁGRA vagy VALAMELY CÉLRA
// VALÓ ALKALMAZHATÓSÁGRA való származtatott garanciát is beleértve.
// További részleteket a GNU General Public License tartalmaz.
//
// A felhasználónak a programmal együtt meg kell kapnia a GNU General
// Public License egy példányát; ha mégsem kapta meg, akkor
// tekintse meg a <http://www.gnu.org/licenses/> oldalon.
//
//
// Version history:
//
// 0.0.1,       http://progpater.blog.hu/2011/02/19/gyonyor_a_tomor
// 0.0.2,       csomópontok mutatóinak NULLázása (nem fejtette meg senki :)
// 0.0.3,       http://progpater.blog.hu/2011/03/05/labormeres_otthon_avagy_hogyan_dolgozok_fel_egy_pedat
// 0.0.4,       z.cpp: a C verzióból svn: bevezetes/C/ziv/z.c átírjuk C++-ra
//              http://progpater.blog.hu/2011/03/31/imadni_fogjatok_a_c_t_egy_emberkent_tiszta_szivbol
// 0.0.5,       z2.cpp: az fgv(*mut)-ok helyett fgv(&ref)
// 0.0.6,       z3.cpp: Csomopont beágyazva
//              http://progpater.blog.hu/2011/04/01/imadni_fogjak_a_c_t_egy_emberkent_tiszta_szivbol_2
// 0.0.6.1      z3a2.c: LZWBinFa már nem barátja a Csomopont-nak, mert annak tagjait nem használja direktben
// 0.0.6.2      Kis kommentezést teszünk bele 1. lépésként (hogy a kicsit lemaradt hallgatóknak is
//              könnyebb legyen, jól megtűzdeljük további olvasmányokkal)
//              http://progpater.blog.hu/2011/04/14/egyutt_tamadjuk_meg
//              (majd a 2. lépésben "beletesszük a d.c-t", majd s 3. lépésben a parancssorsor argok feldolgozását)
// 0.0.6.3      z3a2.c: Fejlesztgetjük a forrást: http://progpater.blog.hu/2011/04/17/a_tizedik_tizenegyedik_labor
// 0.0.6.4      SVN-beli, http://www.inf.unideb.hu/~nbatfai/p1/forrasok-SVN/bevezetes/vedes/
// 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
// 0.0.6.6      z3a5.cpp: mamenyaka kolléga észrevételére a több komment sor figyelmen kívül hagyása
//		http://progpater.blog.hu/2012/03/20/a_vedes_elokeszitese/fullcommentlist/1#c16150365
// 0.0.6.7	Javaslom ezt a verziót választani védendő programnak
// 0.0.6.8	z3a7.cpp: pár kisebb javítás, illetve a védések támogatásához további komment a <<
// 		eltoló operátort tagfüggvényként, illetve globális függvényként túlterhelő részekhez.
//		http://progpater.blog.hu/2012/04/10/imadni_fogjak_a_c_t_egy_emberkent_tiszta_szivbol_4/fullcommentlist/1#c16341099
//

#include <iostream>		// mert olvassuk a std::cin, írjuk a std::cout csatornákat
#include <cmath>		// mert vonunk gyököt a szóráshoz: std::sqrt
#include <fstream>		// fájlból olvasunk, írunk majd

/* Az LZWBinFa osztályban absztraháljuk az LZW algoritmus bináris fa építését. Az osztály
 definíciójába beágyazzuk a fa egy csomópontjának az absztrakt jellemzését, ez lesz a
 beágyazott Csomopont osztály. Miért ágyazzuk be? Mert külön nem szánunk neki szerepet, ezzel
 is jelezzük, hogy csak a fa részeként számiolunk vele.*/

class LZWBinFa
{
public:
  /* Szemben a bináris keresőfánkkal (BinFa osztály)
     http://progpater.blog.hu/2011/04/12/imadni_fogjak_a_c_t_egy_emberkent_tiszta_szivbol_3
     itt (LZWBinFa osztály) a fa gyökere nem pointer, hanem a '/' betüt tartalmazó objektum,
     lásd majd a védett tagok között lent: Csomopont gyoker;
     A fa viszont már pointer, mindig az épülő LZW-fánk azon csomópontjára mutat, amit az
     input feldolgozása során az LZW algoritmus logikája diktál:
     http://progpater.blog.hu/2011/02/19/gyonyor_a_tomor
     Ez a konstruktor annyit csinál, hogy a fa mutatót ráállítja a gyökérre. (Mert ugye
     laboron, blogon, előadásban tisztáztuk, hogy a tartalmazott tagok, most "Csomopont gyoker"
     konstruktora előbb lefut, mint a tagot tartalmazó LZWBinFa osztály konstruktora, éppen a
     következő, azaz a fa=&gyoker OK.)
   */
  LZWBinFa ():fa (&gyoker)
  {
  }
   ~LZWBinFa ()
  {
    szabadit (gyoker.egyesGyermek ());
    szabadit (gyoker.nullasGyermek ());
  }

  /* Tagfüggvényként túlterheljük a << operátort, ezzel a célunk, hogy felkeltsük a
     hallgató érdeklődését, mert ekkor így nyomhatjuk a fába az inputot: binFa << b; ahol a b
     egy '0' vagy '1'-es betű.
     Mivel tagfüggvény, így van rá "értelmezve" az aktuális (this "rejtett paraméterként"
     kapott ) példány, azaz annak a fának amibe éppen be akarjuk nyomni a b betűt a tagjai
     (pl.: "fa", "gyoker") használhatóak a függvényben.

     A függvénybe programoztuk az LZW fa építésének algoritmusát tk.:
     http://progpater.blog.hu/2011/02/19/gyonyor_a_tomor

     a b formális param az a betű, amit éppen be kell nyomni 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
     tagfüggvényként, hogy binFa.operator<<(b) (globálisként így festene: operator<<(binFa, b) )
          
     */
  void operator<< (char b)
  {
    // Mit kell betenni éppen, '0'-t?
    if (b == '0')
      {
	/* Van '0'-s gyermeke az aktuális csomópontnak?
	   megkérdezzük Tőle, a "fa" mutató éppen reá mutat */
	if (!fa->nullasGyermek ())	// ha nincs, hát akkor csinálunk
	  {
	    // elkészítjük, azaz páldányosítunk a '0' betű akt. parammal
	    Csomopont *uj = new Csomopont ('0');
	    // az aktuális csomópontnak, ahol állunk azt üzenjük, hogy
	    // jegyezze már be magának, hogy nullás gyereke mostantól van
	    // küldjük is Neki a gyerek címét:
	    fa->ujNullasGyermek (uj);
	    // és visszaállunk a gyökérre (mert ezt diktálja az alg.)
	    fa = &gyoker;
	  }
	else			// ha van, arra rálépünk
	  {
	    // azaz a "fa" pointer már majd a szóban forgó gyermekre mutat:
	    fa = fa->nullasGyermek ();
	  }
      }
    // Mit kell betenni éppen, vagy '1'-et?
    else
      {
	if (!fa->egyesGyermek ())
	  {
	    Csomopont *uj = new Csomopont ('1');
	    fa->ujEgyesGyermek (uj);
	    fa = &gyoker;
	  }
	else
	  {
	    fa = fa->egyesGyermek ();
	  }
      }
  }
  /* A bejárással kapcsolatos függvényeink (túlterhelt kiir-ók, atlag, ratlag stb.) rekurzívak,
     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)

     (Ha a rekurzív függvénnyel általában gondod van => K&R könyv megfelelő része: a 3. ea. izometrikus
     részében ezt "letáncoltuk" :) és külön idéztük a K&R álláspontját :)
   */
  void kiir (void)
  {
    // Sokkal elegánsabb lenne (és más, a bevezetésben nem kibontandó reentráns kérdések miatt is, mert
    // ugye ha most két helyről hívják meg az objektum ilyen függvényeit, tahát ha kétszer kezd futni az
    // objektum kiir() fgv.-e pl., az komoly hiba, mert elromlana a mélység... tehát a mostani megoldásunk
    // nem reentráns) ha nem használnánk a C verzióban globális változókat, a C++ változatban példánytagot a
    // mélység kezelésére: http://progpater.blog.hu/2011/03/05/there_is_no_spoon
    melyseg = 0;
    // ha nem mondta meg a hívó az üzenetben, hogy hova írjuk ki a fát, akkor a
    // sztenderd out-ra nyomjuk
    kiir (&gyoker, std::cout);
  }
  /* már nem használjuk, tartalmát a dtor hívja
  void szabadit (void)
  {
    szabadit (gyoker.egyesGyermek ());
    szabadit (gyoker.nullasGyermek ());
    // magát a gyökeret nem szabadítjuk, hiszen azt nem mi foglaltuk a szabad tárban (halmon).
  }
  */

  /* A változatosság kedvéért ezeket az osztálydefiníció (class LZWBinFa {...};) után definiáljuk,
     hogy kénytelen légy az LZWBinFa és a :: hatókör operátorral minősítve definiálni :) l. lentebb */
  int getMelyseg (void);
  double getAtlag (void);
  double getSzoras (void);

  /* Vágyunk, hogy a felépített LZW fát ki tudjuk nyomni ilyenformán: std::cout << binFa;
     de mivel a << operátor is a sztenderd névtérben van, de a using namespace std-t elvből
     nem használjuk bevezető kurzusban, így ez a konstrukció csak az argfüggő névfeloldás miatt
     fordul le (B&L könyv 185. o. teteje) ám itt nem az a lényeg, hanem, hogy a cout ostream
     osztálybeli, így abban az osztályban kéne módosítani, hogy tudjon kiírni LZWBinFa osztálybelieket...
     e helyett a globális << operátort terheljük túl, 
     
     a kiFile << binFa azt jelenti, hogy
     
      - tagfüggvényként: kiFile.operator<<(binFa) de ehhez a kiFile valamilyen
      std::ostream stream osztály forrásába kellene beleírni ezt a tagfüggvényt,
      amely ismeri a mi LZW binfánkat...
      
      - globális függvényként: operator<<(kiFile, binFa) és pont ez látszik a következő sorban:
     
     */
  friend std::ostream & operator<< (std::ostream & os, LZWBinFa & bf)
  {
    bf.kiir (os);
    return os;
  }
  void kiir (std::ostream & os)
  {
    melyseg = 0;
    kiir (&gyoker, os);
  }

private:
  class Csomopont
  {
  public:
    /* A paraméter nélküli konstruktor az elepértelmezett '/' "gyökér-betűvel" hozza
       létre a csomópontot, ilyet hívunk a fából, aki tagként tartalmazza a gyökeret.
       Máskülönben, ha valami betűvel hívjuk, akkor azt teszi a "betu" tagba, a két
       gyermekre mutató mutatót pedig nullra állítjuk, C++-ban a 0 is megteszi. */
  Csomopont (char b = '/'):betu (b), balNulla (0), jobbEgy (0)
    {
    };
    ~Csomopont ()
    {
    };
    // Aktuális csomópont, mondd meg nékem, ki a bal oldali gyermeked
    // (a C verzió logikájával műxik ez is: ha nincs, akkor a null megy vissza)
    Csomopont *nullasGyermek () const
    {
      return balNulla;
    }
    // Aktuális csomópon,t mondd meg nékem, ki a jobb oldali gyermeked?
    Csomopont *egyesGyermek () const
    {
      return jobbEgy;
    }
    // Aktuális csomópont, ímhol legyen a "gy" mutatta csomópont a bal oldali gyereked!
    void ujNullasGyermek (Csomopont * gy)
    {
      balNulla = gy;
    }
    // Aktuális csomópont, ímhol legyen a "gy" mutatta csomópont a jobb oldali gyereked!
    void ujEgyesGyermek (Csomopont * gy)
    {
      jobbEgy = gy;
    }
    // Aktuális csomópont: Te milyen betűt hordozol?
    // (a const kulcsszóval jelezzük, hogy nem bántjuk a példányt)
    char getBetu () const
    {
      return betu;
    }

  private:
    // friend class LZWBinFa; /* mert ebben a valtozatban az LZWBinFa metódusai nem közvetlenül
    // a Csomopont tagjaival dolgoznak, hanem beállító/lekérdező üzenetekkel érik el azokat */

    // Milyen betűt hordoz a csomópont
    char betu;
    // Melyik másik csomópont a bal oldali gyermeke? (a C változatból "örökölt" logika:
    // ha hincs ilyen csermek, akkor balNulla == null) igaz
    Csomopont *balNulla;
    Csomopont *jobbEgy;
    // nem másolható a csomópont (ökörszabály: ha van valamilye a szabad tárban,
    // letiltjuk a másoló konstruktort, meg a másoló értékadást)
    Csomopont (const Csomopont &);
    Csomopont & operator= (const Csomopont &);
  };

  /* Mindig a fa "LZW algoritmus logikája szerinti aktuális" csomópontjára mutat */
  Csomopont *fa;
  // technikai
  int melyseg, atlagosszeg, atlagdb;
  double szorasosszeg;
  // szokásosan: nocopyable
  LZWBinFa (const LZWBinFa &);
  LZWBinFa & operator= (const LZWBinFa &);

  /* Kiírja a csomópontot az os csatornára. A rekurzió kapcsán lásd a korábbi K&R-es utalást... */
  void kiir (Csomopont * elem, std::ostream & os)
  {
    // Nem létező csomóponttal nem foglalkozunk... azaz ez a rekurzió leállítása
    if (elem != NULL)
      {
	++melyseg;
	kiir (elem->egyesGyermek (), 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->getBetu () << "(" << melyseg - 1 << ")" << std::endl;
	kiir (elem->nullasGyermek (), os);
	--melyseg;
      }
  }
  void szabadit (Csomopont * elem)
  {
    // Nem létező csomóponttal nem foglalkozunk... azaz ez a rekurzió leállítása
    if (elem != NULL)
      {
	szabadit (elem->egyesGyermek ());
	szabadit (elem->nullasGyermek ());
	// ha a csomópont mindkét gyermekét felszabadítottuk
	// azután szabadítjuk magát a csomópontot:
	delete elem;
      }
  }

protected:			// ha esetleg egyszer majd kiterjesztjük az osztályt, mert
// akarunk benne valami újdonságot csinálni, vagy meglévő tevékenységet máshogy... stb.
// akkor ezek látszanak majd a gyerek osztályban is

  /* A fában tagként benne van egy csomópont, ez erősen ki van tüntetve, Ő a gyökér: */
  Csomopont gyoker;
  int maxMelyseg;
  double atlag, szoras;

  void rmelyseg (Csomopont * elem);
  void ratlag (Csomopont * elem);
  void rszoras (Csomopont * elem);

};

// Néhány függvényt az osztálydefiníció után definiálunk, hogy lássunk ilyet is ... :)
// Nem erőltetjük viszont a külön fájlba szedést, mert a sablonosztályosított tovább
// fejlesztésben az linkelési gondot okozna, de ez a téma már kivezet a laborteljesítés
// szükséges feladatából: http://progpater.blog.hu/2011/04/12/imadni_fogjak_a_c_t_egy_emberkent_tiszta_szivbol_3

// Egyébként a melyseg, atlag és szoras fgv.-ek a kiir fgv.-el teljesen egy kaptafa.

int
LZWBinFa::getMelyseg (void)
{
  melyseg = maxMelyseg = 0;
  rmelyseg (&gyoker);
  return maxMelyseg - 1;
}

double
LZWBinFa::getAtlag (void)
{
  melyseg = atlagosszeg = atlagdb = 0;
  ratlag (&gyoker);
  atlag = ((double) atlagosszeg) / atlagdb;
  return atlag;
}

double
LZWBinFa::getSzoras (void)
{
  atlag = getAtlag ();
  szorasosszeg = 0.0;
  melyseg = atlagdb = 0;

  rszoras (&gyoker);

  if (atlagdb - 1 > 0)
    szoras = std::sqrt (szorasosszeg / (atlagdb - 1));
  else
    szoras = std::sqrt (szorasosszeg);

  return szoras;
}

void
LZWBinFa::rmelyseg (Csomopont * elem)
{
  if (elem != NULL)
    {
      ++melyseg;
      if (melyseg > maxMelyseg)
	maxMelyseg = melyseg;
      rmelyseg (elem->egyesGyermek ());
      // ez a postorder bejáráshoz képest
      // 1-el nagyobb mélység, ezért -1
      rmelyseg (elem->nullasGyermek ());
      --melyseg;
    }
}

void
LZWBinFa::ratlag (Csomopont * elem)
{
  if (elem != NULL)
    {
      ++melyseg;
      ratlag (elem->egyesGyermek ());
      ratlag (elem->nullasGyermek ());
      --melyseg;
      if (elem->egyesGyermek () == NULL && elem->nullasGyermek () == NULL)
	{
	  ++atlagdb;
	  atlagosszeg += melyseg;
	}
    }
}

void
LZWBinFa::rszoras (Csomopont * elem)
{
  if (elem != NULL)
    {
      ++melyseg;
      rszoras (elem->egyesGyermek ());
      rszoras (elem->nullasGyermek ());
      --melyseg;
      if (elem->egyesGyermek () == NULL && elem->nullasGyermek () == NULL)
	{
	  ++atlagdb;
	  szorasosszeg += ((melyseg - atlag) * (melyseg - atlag));
	}
    }
}

// teszt pl.: http://progpater.blog.hu/2011/03/05/labormeres_otthon_avagy_hogyan_dolgozok_fel_egy_pedat
// [norbi@sgu ~]$ echo "01111001001001000111"|./z3a2
// ------------1(3)
// ---------1(2)
// ------1(1)
// ---------0(2)
// ------------0(3)
// ---------------0(4)
// ---/(0)
// ---------1(2)
// ------0(1)
// ---------0(2)
// depth = 4
// mean = 2.75
// var = 0.957427
// a laborvédéshez majd ezt a tesztelést használjuk:
// http://

/* Ez volt eddig a main, de most komplexebb kell, mert explicite bejövő, kimenő fájlokkal kell dolgozni
int
main ()
{
    char b;
    LZWBinFa binFa;

    while (std::cin >> b)
    {
        binFa << b;
    }

    //std::cout << binFa.kiir (); // így rajzolt ki a fát a korábbi verziókban de, hogy izgalmasabb legyen
    // a példa, azaz ki lehessen tolni az LZWBinFa-t kimeneti csatornára:

    std::cout << binFa; // ehhez kell a globális operator<< túlterhelése, lásd fentebb

    std::cout << "depth = " << binFa.getMelyseg () << std::endl;
    std::cout << "mean = " << binFa.getAtlag () << std::endl;
    std::cout << "var = " << binFa.getSzoras () << std::endl;

    binFa.szabadit ();

    return 0;
}
*/

/* A parancssor arg. kezelést egyszerűen bedolgozzuk a 2. hullám kapcsolódó feladatából:
 http://progpater.blog.hu/2011/03/12/hey_mikey_he_likes_it_ready_for_more_3
 de mivel nekünk sokkal egyszerűbb is elég, alig hagyunk meg belőle valamit...
 */

void
usage (void)
{
  std::cout << "Usage: lzwtree in_file -o out_file" << std::endl;
}

int
main (int argc, char *argv[])
{
  // http://progpater.blog.hu/2011/03/12/hey_mikey_he_likes_it_ready_for_more_3
  // alapján a parancssor argok ottani elegáns feldolgozásából kb. ennyi marad:
  // "*((*++argv)+1)"...

  // a kiírás szerint ./lzwtree in_file -o out_file alakra kell mennie, ez 4 db arg:
  if (argc != 4)
    {
      // ha nem annyit kapott a program, akkor felhomályosítjuk erről a júzetr:
      usage ();
      // és jelezzük az operációs rendszer felé, hogy valami gáz volt...
      return -1;
    }

  // "Megjegyezzük" a bemenő fájl nevét
  char *inFile = *++argv;

  // a -o kapcsoló jön?
  if (*((*++argv) + 1) != 'o')
    {
      usage ();
      return -2;
    }

  // ha igen, akkor az 5. előadásból kimásoljuk a fájlkezelés C++ változatát:
  std::fstream beFile (inFile, std::ios_base::in);

  // fejlesztgetjük a forrást: http://progpater.blog.hu/2011/04/17/a_tizedik_tizenegyedik_labor
  if (!beFile)
    {
      std::cout << inFile << " nem letezik..." << std::endl;
      usage ();
      return -3;
    }

  std::fstream kiFile (*++argv, std::ios_base::out);

  unsigned char b;		// ide olvassik majd a bejövő fájl bájtjait
  LZWBinFa binFa;		// s nyomjuk majd be az LZW fa objektumunkba

  // a bemenetet binárisan olvassuk, de a kimenő fájlt már karakteresen írjuk, hogy meg tudjuk
  // majd nézni... :) l. az említett 5. ea. C -> C++ gyökkettes átírási példáit

  while (beFile.read ((char *) &b, sizeof (unsigned char)))
    if (b == 0x0a)
      break;

  bool kommentben = false;

  while (beFile.read ((char *) &b, sizeof (unsigned char)))
    {

      if (b == 0x3e)
	{			// > karakter
	  kommentben = true;
	  continue;
	}

      if (b == 0x0a)
	{			// újsor 
	  kommentben = false;
	  continue;
	}

      if (kommentben)
	continue;

      if (b == 0x4e)		// N betű
	continue;

      // egyszerűen a korábbi d.c kódját bemásoljuk
      // laboron többször lerajzoltuk ezt a bit-tologatást: 
      // a b-ben lévő bájt bitjeit egyenként megnézzük
      for (int i = 0; i < 8; ++i)
	{
	  // maszkolunk eddig..., most már simán írjuk az if fejébe a legmagasabb helyiértékű bit vizsgálatát
	  // csupa 0 lesz benne a végén pedig a vizsgált 0 vagy 1, az if megmondja melyik:
	  if (b & 0x80)
	    // ha a vizsgált bit 1, akkor az '1' betűt nyomjuk az LZW fa objektumunkba
	    binFa << '1';
	  else
	    // különben meg a '0' betűt:
	    binFa << '0';
	  b <<= 1;
	}

    }

  //std::cout << binFa.kiir (); // így rajzolt ki a fát a korábbi verziókban de, hogy izgalmasabb legyen
  // a példa, azaz ki lehessen tolni az LZWBinFa-t kimeneti csatornára:

  kiFile << binFa;		// ehhez kell a globális operator<< túlterhelése, lásd fentebb
  // (jó ez az OO, mert mi ugye nem igazán erre gondoltunk, amikor írtuk, mégis megy, hurrá)

  kiFile << "depth = " << binFa.getMelyseg () << std::endl;
  kiFile << "mean = " << binFa.getAtlag () << std::endl;
  kiFile << "var = " << binFa.getSzoras () << std::endl;

  kiFile.close ();
  beFile.close ();

  return 0;
}

 

 

 

*: "Imádni fogják a légiót, egy emberként, tiszta szívből", www.imdb.com/title/tt0126388/

55 komment

A védés előkészítése

2012.03.20. 10:02 nb

Ez a poszt az év közbeni védést támogatja. Laborfeladatként a védés "C vetületét" készítjük el. Itt nem adok teljes kódot, hogy a hallgató rá legyen szorítva az önálló munkára. (A közelgő aktuális védésre ez nem igaz, hiszen az annak alapjául szolgáló teljes kód itt van pl.: z3a5.cpp)

A jelen labor annyiban készíti elő a (C++ alapú) védést, hogy ugyanerre a bemenetre kell majd működnie a védésnek, s visszatekintve látható lesz, hogy a C kód ismerete mennyire segíti a C++ változat jó olvashatóságát.

Tehát a laboron egy olyan programot kell készítened, amely

  • parancssor argumentumként átveszi a bemenő állomány nevét, majd a -o kapcsolóval jelzett kimenő állomány nevét, ilyen sorrendben (a parancssor argumentumok kezelését a C++ változatból is kinézheted, vagy itt egy általános ilyen kódcsipet az egyik trófeás feladatnál)
  • binárisan dolgozza fel a fájlt: már az eredeti z.c is a read-el olvasott be, de aztán, mint karaktert vizsgálta a beolvasott bájtot, amelyet most bitenként kell feldolgoznod (azaz ide a d.c egy klónját bedolgoznod), így végül a 2. kromó TCAG betűinek bitjeit dolgozod fel (az N-eket, fájl eleji kommentet, az újsor jelek bitjeit viszont hagyd figyelmen kívül)
  • eredményül kinyomtatja a kimenő állományba a fát, majd annak mélységét, ághosszainak átlagát és szórását (ez utóbbiak gyakorlatilag a fa bejárását feltételezik, amit már valószínűleg rongyosra olvastál a K&R könyvben.)

 Minek kell kijönnie, avagy Mérő László nyomán "ebben a félévben így működik a vese" (l., még a következő kommentet is.)

nbatfai@hallg:~/bevezetes/vedes/2012tavasz$ g++ z3a5.cpp -o lzwtree
nbatfai@hallg:~/bevezetes/vedes/2012tavasz$ ./lzwtree hs_alt_HuRef_chr2.fa -o hs_alt_HuRef_chr2.fa.lzwtree
nbatfai@hallg:~/bevezetes/vedes/2012tavasz$ tail -n 3 hs_alt_HuRef_chr2.fa.lzwtree
depth = 291
mean = 77.9101
var = 8.81904
ahol neked természetesen a saját C kódoddal kell dolgoznod!
 

"Hey, Mikey, he likes it! Ready for more?"*

A kurzus krémjének már biztosan megvan a képessége, hogy kedvére tudjon csemegézni a tavalyi szabadon választható feladatok első két hullámából, ezt mostantól megtehetik:

Nyilván, olyan feladatot, amit már elszámoltál és itt is szerepel, ne süsd el újra.

Indul a Qt!

 Akiknek ez már lerágott csont, élesszék fel a bevezető Qt példákat, vagy a Creator-ban, vagy parancssorból: Tán csodállak, ámde nem értelek, de képzetem hegyvölgyedet bejárja*

[norbert@matrica 5]$ ls -l
total 24
-rw-rw-r--. 1 norbert norbert 3169 Mar 21 09:56 frakablak.cpp
-rw-rw-r--. 1 norbert norbert  633 Mar 21 09:56 frakablak.h
-rw-rw-r--. 1 norbert norbert 4736 Mar 21 09:56 frakszal.cpp
-rw-rw-r--. 1 norbert norbert  795 Mar 21 09:56 frakszal.h
-rw-rw-r--. 1 norbert norbert 1408 Mar 21 09:56 main.cpp
[norbert@matrica 5]$ qmake-qt4 -project
[norbert@matrica 5]$ ls -l
total 28
-rw-rw-r--. 1 norbert norbert  359 Mar 21 11:18 5.pro
-rw-rw-r--. 1 norbert norbert 3169 Mar 21 09:56 frakablak.cpp
-rw-rw-r--. 1 norbert norbert  633 Mar 21 09:56 frakablak.h
-rw-rw-r--. 1 norbert norbert 4736 Mar 21 09:56 frakszal.cpp
-rw-rw-r--. 1 norbert norbert  795 Mar 21 09:56 frakszal.h
-rw-rw-r--. 1 norbert norbert 1408 Mar 21 09:56 main.cpp
[norbert@matrica 5]$ qmake-qt4 5.pro
[norbert@matrica 5]$ ls -l
total 36
-rw-rw-r--. 1 norbert norbert  359 Mar 21 11:18 5.pro
-rw-rw-r--. 1 norbert norbert 3169 Mar 21 09:56 frakablak.cpp
-rw-rw-r--. 1 norbert norbert  633 Mar 21 09:56 frakablak.h
-rw-rw-r--. 1 norbert norbert 4736 Mar 21 09:56 frakszal.cpp
-rw-rw-r--. 1 norbert norbert  795 Mar 21 09:56 frakszal.h
-rw-rw-r--. 1 norbert norbert 1408 Mar 21 09:56 main.cpp
-rw-rw-r--. 1 norbert norbert 7831 Mar 21 11:19 Makefile
[norbert@matrica 5]$ make
[norbert@matrica 5]$ ./5

 Trófeák a laborközösségekben:

  • 3/2: legyen csak piros árnyalat (+.5 csak zöld)
  • 1/1: közönségdíj a legszebbnek
  • -/2[+5]: legalább 5 egymásból nagyított kép, 'S'-re menti fájlba, [képek fel a Facebook-ra, a vasárnap éjfélig legtöbb lájkot kapó]
  • 3/2: betűre gyorsítja/lassítja a sejttér működését
  • 3/4: betűre kicsinyíti, nagyítja a sejttér megjelenő méretét
  • -/2[+5]: mik a Conway-f életjáték szabályai (a kód alapján, azt magyarázva kérem a választ), [találj ki saját szabályt és szép eredmény képet/videót fel a Facebook-ra, a vasárnap éjfélig legtöbb lájkot kapó]

Linux: visszajövök

Az előző két poszthoz, persze a virtualizált rendszert akár egy Win hoszt rendszeren is használhatod, de ez felségárulás:

 Itt a tavasz, elő a focit!

Aki reprodukál egy GoldenTeam FC - GoldenTeam B mérkőzést, 4 trófeát kap, ha mindehez készít egy rövid tutoriál jellegű leírást is a társainak, akkor x2=8, itt a virtualizált támogatás. S az egész megismételhető, ha egy GoldenTeam FC- HELIOS_Base mérkőzést játszunk le, azaz első körben a robotfocival 16 trófea kaszírozható (az első 3 hallgatót díjazzuk, s RCG-t is kérek bemutatni).

*: www.imsdb.com/scripts/Matrix,-The.html

118 komment

Címkék: védés humán genom 2 kromoszóma

süti beállítások módosítása