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 bejegyzés trackback címe:

https://progpater.blog.hu/api/trackback/id/tr594380983

Kommentek:

A hozzászólások a vonatkozó jogszabályok  értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai  üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a  Felhasználási feltételekben és az adatvédelmi tájékoztatóban.

thevr 2012.04.11. 10:49:39

Valaki ehhez tudna egy kis magyarázatot adni:

friend std::ostream & operator<< (std::ostream & os, LZWBinFa & bf)
{
bf.kiir (os);
return os;
}

Ezt a friend-es részt nem igazán értem.

Köszönöm!

nb · http://fersml.blog.hu 2012.04.11. 11:40:44

frissítettem a posztot a z3a7.cpp-vel, amelynek kommentjeiben írtam pár sort az << eltoló operátort tagfüggvényként, illetve globális függvényként túlterhelő részeknél, de beszéljünk róla aztán bátran!

2012.04.11. 14:43:59

A program kiegészítve egy-két dologgal (pl. mutatja, hogy hol tart a beolvasásban; lehet csak az eredményt kiírni file-ba (nem az egész fát); stb)

www13.zippyshare.com/v/25138929/file.html

használathoz: --help

kepfeltoltes.hu/120411/Screenshot_at_2012-04-11_14_41_56_www.kepfeltoltes.hu_.png

2012.04.11. 15:00:00

Alt. Tab.:

Minden egyben forráskód:
www38.zippyshare.com/v/9968724/file.html

Hozzá tartozó bemeneti file-ok:
22. forduló: www9.zippyshare.com/v/54663742/file.html
23. forduló: www5.zippyshare.com/v/35306804/file.html

2012.04.11. 17:02:39

@nb: Alt. Tab. LaLiga: 31 fordulo utan

Barcelona....................0.071529
Real Madrid..................0.066419
Valencia.....................0.064666
Osasuna......................0.057895
Villarreal...................0.055648
Athletic Bilbao..............0.054732
Levante......................0.053392
Malaga.......................0.053038
Sevilla FC...................0.052903
Getafe.......................0.052601
Espanyol.....................0.049945
Racing Santander.............0.047837
Atletico Madrid..............0.046275
Real Sociedad................0.045498
Mallorca.....................0.045373
Real Betis...................0.039293
Rayo Vallecano...............0.038555
Real Zaragoza................0.036224
Granada......................0.035819
Sporting Gijon...............0.032359

forrasfile: www24.zippyshare.com/v/6638285/file.html
adatok:
www64.zippyshare.com/v/30598344/file.html

2012.04.11. 17:05:29

@nb: Csak egyetlen kérdésem lenne:
20 csapattal dolgozok, kell változtatni valamit a kódban?
Van ott egy d = 0.87, az pontosan mi és hogy jött ki?

2012.04.11. 18:31:37

Labor:
2 pont magyarázat: kiFile << a << b << ...
1 pont bizonyíték-printf végtelen ciklus előtt

2012.04.11. 21:58:44

Alt. Tab.:
Uj programmal a 22. fordulo:
www21.zippyshare.com/v/5127358/file.html

Debreceni VSC........0.093449
Pecsi MFC............0.079139
Kaposvari Rakoczi....0.078364
Budapest Honved......0.078001
Videoton.............0.067854
Gyori ETO............0.067326
BFC Siofok...........0.064194
Kecskemιti TE........0.063688
Haladas..............0.060847
Vasas................0.057452
Paksi FC.............0.056471
Diosgyor.............0.054524
Lombard Papa.........0.052090
Ferencvaros..........0.049963
Ujpest...............0.039374
Zalaegerszegi TE.....0.037268

bemenet:
www14.zippyshare.com/v/42059031/file.html

devilirium 2012.04.12. 09:04:44

Labor, 5 pont, genom, c++ kod celebralas.

KDániel 2012.04.12. 09:37:07

1 pont a bizonyításért

almatkortet 2012.04.12. 12:15:44

0,5 pont a progpaterben a gyermek szülője PID hiba felismerése

3 pont crashme
nem ölte meg a virtuális gépet, de a filmnézésbe bekavart a 40. perc környékén a windowsba

kepfeltoltes.hu/view/120412/Untitled_17_www.kepfeltoltes.hu_.jpg

thevr 2012.04.12. 17:40:42

Celebrálás: 4 pont + 0.5 pont a sigjmp-s bizonyításért

devilirium 2012.04.13. 07:10:29

Tegnap még én is meg Munkácsi Zoli is lefuttattuk a crashmet, dehát nem sikerült crasheltetni. Nekem 2 órát futott neki 2+x.

bensz92 2012.04.13. 20:21:56

0,5 pont progpater forkos példa magyarázás

mamenyaka (törölt) 2012.04.14. 15:35:45

Alt. Tab.:
Az "uj program" bemeneti file-jában van egy hiba - az egyetlen szerdai meccs "Wed" szócskája bentmaradt, emiatt lett más az eredmény.

A mostmár wikipédiás meccs eredményekből beolvasó program a jó eredményt hozza ki. (22. forduló)

www38.zippyshare.com/v/32696886/file.html

Ezzel számolva a 23. forduló:

Debreceni VSC........0.092757
Pecsi MFC............0.078061
Budapest Honved......0.075710
BFC Siofok...........0.074870
Kaposvari Rakoczi....0.074301
Gyori ETO............0.068902
Haladas..............0.065563
Videoton.............0.065403
Kecskemιti TE........0.062410
Paksi FC.............0.058214
Vasas................0.054032
Diosgyor.............0.053555
Lombard Papa.........0.049477
Ferencvaros..........0.048714
Ujpest...............0.042334
Zalaegerszegi TE.....0.035698

Bemenet:
www15.zippyshare.com/v/56176377/file.html

A "–" karaktereket le kell cserélni "-" karakterekre, ha új fordulók eredményeit copy-pasteljük.

!!!Elnézést mindenkitől a sok focis spam miatt!!!

almatkortet 2012.04.16. 23:51:46

A kernel fordítást szeretném próbálgatni, de a vitrualbox kép már nem elérhető :(

Valaki tud segíteni?

nimuss 2012.04.18. 13:16:40

Toma89 és az eredeti program sebességének összevetése +2p

devilirium 2012.04.18. 13:34:44

Az előadás 6. fólia, 35. oldalán tárgyalt kódrészletében zavart észleltem; az std::endl már alapból elvégzi az utána következő std::flush szerepét. +1p

www.cplusplus.com/reference/iostream/manipulators/endl/

Rosti21 2012.04.18. 19:41:13

Nagyon megkésve de el is felejtkeztem róla:
Előző héten, a csütörtöki 16-18 közötti órán Tanár Úr által feltett kérdésre helyesen válaszoltam fél pontért.

R István

KDániel 2012.04.19. 08:51:12

Laboron +1pont a védésen feltett kérdés megválaszolásáért.

almatkortet 2012.04.19. 17:31:02

többszálas exortörés:

gyazo.com/7aad3baaba6a57605509a4f7aab0c9ae

nem vagyok benne biztos h így ezt kell kapnom, de egy maggal lassú virtuális géppel ezt sikerült kihozni belőle

*bohóc* 2012.04.19. 18:00:20

+1 pont a mai laboron
operator << (operator << (cout, "a"), "b")

mamenyaka (törölt) 2012.04.19. 18:27:57

Alt. Tab.:
24. fordulo

Debreceni VSC........0.093098
BFC Siofok...........0.074830
Kaposvari Rakoczi....0.073810
Pecsi MFC............0.073708
Budapest Honved......0.071413
Gyori ETO............0.070610
Paksi FC.............0.066061
Videoton.............0.064997
Haladas..............0.062525
Kecskemιti TE........0.059967
Ferencvaros..........0.055452
Vasas................0.052419
Diosgyor.............0.051791
Lombard Papa.........0.050108
Ujpest...............0.045084
Zalaegerszegi TE.....0.034129

matrix:
X 0 1 1 3 2 0 3 1 3 2 0 1 1 1 1
2 X 1 1 1 0 0 1 2 1 0 2 1 1 1 1
0 0 X 3 1 1 1 3 1 3 1 1 1 0 3 1
2 3 2 X 2 3 2 0 0 2 3 0 1 1 3 1
3 0 0 1 X 1 1 1 1 1 0 1 1 1 1 1
3 3 0 1 2 X 2 2 1 0 2 1 0 1 2 1
2 2 1 2 2 0 X 1 1 2 0 3 2 2 1 0
1 3 1 1 0 2 1 X 1 3 3 1 0 2 0 1
1 3 3 3 0 1 1 0 X 1 2 1 3 2 3 0
0 2 2 0 3 1 2 1 2 X 2 2 1 0 3 1
0 2 0 3 1 1 2 2 1 0 X 2 2 1 3 1
2 2 1 3 3 0 1 0 1 1 1 X 1 2 2 0
1 3 2 0 3 1 1 1 3 3 1 2 X 0 0 1
3 2 3 1 3 2 0 3 0 1 3 0 1 X 2 1
1 3 1 0 0 1 1 3 0 1 1 1 1 1 X 1
3 3 2 3 3 2 2 2 2 0 2 2 0 2 0 X

pocpac 2012.04.19. 18:54:19

2x félpont a mai laboron: kviz1 és kviz2
Lakatos Gábor

devilirium 2012.04.19. 19:57:17

Nos, OpenMP kísérletezés Exorral. Kicsit hosszadalmasra sikerült és 7 percem van már csak, amikor ezeket a sorokat írom, de azért itt van:

// A kód
ideone.com/yd2ds

// Képek
i.imgur.com/I2z3K.png
i.imgur.com/GkzEC.png
i.imgur.com/kRK09.png

devilirium 2012.04.19. 20:01:08

Ohh, és azt elfelejtettem mondani, hogy redukáltam a kulcs hosszúságát 6-ra, mert becrasheltek a gnome-terminalok és amúgy is hihetetlenül lassan futott, még így is. Szegénykém megvan terhelve, de azért látszik a gyorsulás =)

A for ciklusokat is átszerkesztettem alapból, mert nem találtam elegáns megoldásnak, így lehet, hogy az OpenMP nem segített oly sokat.

Minden eshetőségre +5 pont, kicsit pihenek, aztán azt hiszem magyarázatot is adok majd egy kicsit később.

KDániel 2012.04.20. 13:33:00

04.19. 8 órás labor +0.5 pont, kvíz2
Azt hittem elküldtem még laboron, de úgy látszik lemaradt

szajbergyerek 2012.04.20. 21:00:20

Csütörtöki 8 órás labor, 0.5 pont a kvíz2 helyes válaszára való tippelésért.

Peterzon92 2012.04.22. 19:27:36

Csináltunk *bohóc*-al egy blogot a laborkártyák nagy részének megoldásával hogy segítsünk titeket a tanulásban, sajnos úgy látszik pontot nem érdemelt az oldal de mi hiszünk benne hogy sokat segít. laborkartya.blog.hu/
Írjatok megjegyzéseket ha valami nem világos. Sajnos egy hétig nem tudunk válaszolni de utána fogunk.

nb · http://fersml.blog.hu 2012.04.22. 20:32:27

@Peterzon92: nem azt írtam, hogy nem érdemel pontot, hanem azt, hogy 5 pont az, ha legalább olyan gazdag, mint a példaként felhozott, ahonnan kapásból be volt linkelve az egyik poszthoz egy 5 oldalas doc fájl stb.

Tehát a jelenlegi "egy soros" formájában nem adnék még rá 5 pontot. 15-öt meg pláne nem :-)))

KDániel 2012.04.24. 20:15:40

"Hey, Mikey, he likes it! Ready for more?"*
progpater.blog.hu/2011/03/12/hey_mikey_he_likes_it_ready_for_more_3

3 kisbajnokságos feladatok - K&R feladat: 5.10 gyakorlat
Úgy hiszem ezt még nem küldték be, szóval itt van:
kepfeltoltes.hu/120424/K_perny_k_p___2012-04-24_20_09_14_www.kepfeltoltes.hu_.png
www.4shared.com/file/dqNu-mo7/exercise510.html

Toma89 2012.04.25. 17:50:45

-/3 Verem feladat:

Megcsináltam az előadás veremmel kapcsolatos robbanófóliáját. Remélem erre gondolt tanárúr.

verem.txt fájlba írattam ki a verem16.cpp módosításának eredményét.

A txt fájl: www66.zippyshare.com/v/31165574/file.html

A módosított forrásfájl: www7.zippyshare.com/v/65049024/file.html

jakaba 2012.04.25. 22:21:29

A mátrix-trógila elemzése Géczy Gábor fizikus, tanár és filozófus által.
www.magyarfoldre.hu/hirek/a_matrix___elemzes
Csak gondoltam belinkelem, mert az informatikus körében közkedvelt a trilógia, meg volt is idézet egy posztcímben. :)
Ha valakinek esetleg tetszik, itt egy másik erősen ajánlott előadás tőle:
kataklizma.info/2012/02/11/az-elet-el-es-elni-akar

thevr 2012.04.26. 16:57:33

Laboron (16:00-18:00) megoldottam a robbanófólia feladatát. +3 trófea

KDániel 2012.04.26. 18:41:24

@nb: Ma ugye laboron úgy sikerült a védésem, hogy gyorsítottam a programon, de ez így veszélyes volt. Most jutott eszembe, egy szerintem jó megoldás ennek kiküszöbölésére. Ha úgy oldanánk meg a getAtlag függvényt, ahogy az az előadáson átvett random szám generátor? Tehát, hogy az első hívás után a függvényen belül eltároljuk a kapott átlagot és a további hívásoknál már csak ezt adnák újra vissza és nem járnánk be újra a fát. Ez így megfelelő? Kár, hogy nem védésen jutott eszembe.

nb · http://fersml.blog.hu 2012.04.26. 19:09:11

@KDániel: remek, esetleg még arra is érdemes figyelni, hogy akkor ha közben változik a fa, úgy vegye, hgy megint nincs átlag számítva és eltárolva (ugye pl. a megfelelő példánytagban).

thevr 2012.04.26. 21:31:28

Gondoltam megosztom, hogy a 2. védendő "kód":

robocup.inf.unideb.hu/fersml/assr/rcsslogplayer-15.0.0.assr.1.tgz

A program bizonyos részeit kell majd megvédenünk, ami hamarosan kiderül.

Előre is sok szerencsét mindenkinek!

KDániel 2012.04.26. 21:32:37

De amikor hívjuk a getAtlag függvényt akkor a fa már készen van, új fa építéséhez meg újra kell hívni magát a progit (a jelenlegi verzió szerint), tehát nem értem, hogy ezt miért kéne figyelembe venni?

nb · http://fersml.blog.hu 2012.04.26. 22:14:09

@KDániel: az LZWBinFa binFa; objektumba bármikor nyomhatunk további betűket a tagfüggvényként túlterhelt eltoló operátorral, tehát ebben az értelemben a fa "soha sincsen kész". Amikor mi a mainben befejeztük a bemenet beolvasását, akkor íratjuk ki azt az állapotot, de akár ugyanabba a fába benyomhatnánk újra az egész inputot, vagy csak egyetlen '0'-t stb. amit akarunk, ezzel változik a fa, azzal együtt az átlaga, szórása stb.

KDániel 2012.04.26. 22:33:18

Igen, ezzel tisztában voltam, ezért írtam, hogy a jelenlegi verzió szerint. :)

KDániel 2012.04.29. 18:38:09

"Hey, Mikey, he likes it! Ready for more?"*
progpater.blog.hu/2011/03/12/hey_mikey_he_likes_it_ready_for_more_3

6 kisbajnokságos feladatok
K&R feladat: 8.1 gyakorlat
A k az eredeti cat program.
kepfeltoltes.hu/120429/458182328asd_www.kepfeltoltes.hu_.png

KDániel 2012.04.29. 19:41:40

"Hey, Mikey, he likes it! Ready for more?"*
progpater.blog.hu/2011/03/12/hey_mikey_he_likes_it_ready_for_more_3

1 kisbajnokságos feladatok
K&R feladat: 2.2 gyakorlat
kepfeltoltes.hu/120429/dsa_www.kepfeltoltes.hu_.png

nb · http://fersml.blog.hu 2012.05.10. 19:26:28

@KDániel: elég ijesztő ennek a kódnak az indentálása...

KDániel 2012.05.11. 08:09:27

Ahogy a binomom mondta: A zseni átlát a káoszon! :D
süti beállítások módosítása