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

Elmondtam milliomezerszer 2

2011.04.03. 13:22 nb

Korábbi posztunkban foglalkoztunk már a szavak számlálásával: előre hivatkozva, a Google MapReduce kapcsán. Most a K&R könyv C struktúrás szószámoló progiját írjuk meg C++-ban a korábbi osztályunk kódjának egyszerűsítésével. Mélyen nyomjuk majd a backspace-t, mert valódi karcsúsítás lesz, hiszen a jelen feladatban nem az LZW algoritmus logikájával, hanem csak a'la nature kell a bináris fát felépíteni.

Megtehetnénk, hogy a túlterhelt << operátor implementációjából hívunk egy ugyanolyan rekurzív függvényt, mint a K&R hasonló funkciójú

struct tnode* tree (struct tnode*, char *)függvénye, de legyünk már egy kicsit kreatívabbak! (Esetünkben persze Csomopont* lenne a struct tnode* helyett.)

 void operator<<(std::string s)
    {
        int e;

        if (csomopont == NULL) {

            csomopont = new Csomopont (s);
            gyoker = csomopont;

        } else if ((e = csomopont->tartalma().compare(s)) == 0) {

            csomopont->novel();

        } else if (e > 0) {

            if (csomopont->balra() == NULL) {
                csomopont->balra(new Csomopont (s));
            } else {
                csomopont = csomopont->balra();
                *this << s;
            }

        } else if (e < 0) {

            if (csomopont->jobbra() == NULL) {
                csomopont->jobbra(new Csomopont (s));
            } else {
                csomopont = csomopont->jobbra();
                *this << s;
            }

        }

        csomopont = gyoker;

    }

 A "csomopont" mindig a gyökértől indul és oda mutat, ahová éppen megpróbáljuk beszúrni a kapott új szót. Kezdetben nincs fa (szemben az LZW-s példánkban a gyökér nem a szabad tárban, hanem a vermen ott volt alapban) ezért az első szóval az if ág felveszi a szót. Aztán a második szó, ha az elsővel egyezik tartalomra, akkor az első else if ág szerint csak növeljük az aktuális csomópont számlálóját, ha kisebb volt a szó, akkor a jobboldali, ha nagyobb akkor a bal oldali részfába (vagy pont fordítva :) kérjük újra a beszúrását.

Kattints a tovább linkre a teljes forrásért, illetve néhány alternatív "szó-számoló" megoldásért.

 

// z6.cpp
//
// LZW fa építő 6. C++ átirata a C valtozatbol (ez már sima bináris fára)
// Programozó Páternoszter
//
// Copyright (C) 2011, 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.7, z4.cpp: az fgv(*mut)-ok helyett fgv(&ref)
// 0.0.8, z5.cpp: template változat
// 0.0.9, z6.cpp: átírva sima bináris fára
//        http://progpater.blog.hu/2011/04/03/elmondtam_milliomezerszer_2

#include <iostream>
#include <string>

class BinFa
{
public:
    BinFa ():csomopont(0), gyoker(0) {}

    void operator<<(std::string s)
    {
        int e;

        if (csomopont == NULL) {

            csomopont = new Csomopont (s);
            gyoker = csomopont;

        } else if ((e = csomopont->tartalma().compare(s)) == 0) {

            csomopont->novel();

        } else if (e > 0) {

            if (csomopont->balra() == NULL) {
                csomopont->balra(new Csomopont (s));
            } else {
                csomopont = csomopont->balra();
                *this << s;
            }

        } else if (e < 0) {

            if (csomopont->jobbra() == NULL) {
                csomopont->jobbra(new Csomopont (s));
            } else {
                csomopont = csomopont->jobbra();
                *this << s;
            }

        }

        csomopont = gyoker;

    }

    void kiir (void)
    {
        melyseg = 0;
        kiir (gyoker);
    }
    void szabadit (void)
    {
        szabadit (gyoker);
    }

private:
    class Csomopont
    {
    public:
        Csomopont (std::string s):szo(s), hanyszor(1), bal (0), jobb (0) {};
        ~Csomopont () {};
        Csomopont *balra () {
            return bal;
        }
        Csomopont *jobbra ()
        {
            return jobb;
        }
        void balra (Csomopont * bal) {
            this->bal = bal;
        }
        void jobbra (Csomopont * jobb)
        {
            this->jobb = jobb;
        }
        std::string& tartalma() {
            return szo;
        }
        void novel() {
            ++hanyszor;
        }
        int volt() {
            return hanyszor;
        }

    private:
        friend class BinFa;
        std::string szo;
        int hanyszor;
        Csomopont *bal;
        Csomopont *jobb;
        Csomopont (const Csomopont &);
        Csomopont & operator=(const Csomopont &);
    };

    Csomopont *gyoker;
    Csomopont *csomopont;
    int melyseg;

    BinFa (const BinFa &);
    BinFa & operator=(const BinFa &);

    void kiir (Csomopont* elem)
    {
        if (elem != NULL)
        {
            ++melyseg;
            kiir (elem->jobb);
            // ez a postorder bejáráshoz képest
            // 1-el nagyobb mélység, ezért -1
            for (int i = 0; i < melyseg; ++i)
                std::cout << "---";
            std::cout << elem->tartalma() << "(" << elem->volt() << ", " << melyseg - 1 << ")" << std::endl;
            kiir (elem->bal);
            --melyseg;
        }
    }
    void szabadit (Csomopont * elem)
    {
        if (elem != NULL)
        {
            szabadit (elem->jobb);
            szabadit (elem->bal);
            delete elem;
        }
    }

};

int
main ()
{
    BinFa binFa;
    std::string s;

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

    /*
        binFa << "barack";
        binFa << "alma";
        binFa << "korte";
        binFa << "alma";
        binFa << "ribizli";
        binFa << "dio";
        binFa << "cseresznye";
        binFa << "ribizli";
        binFa << "ribizli";
        binFa << "ribizli";
        binFa << "banan";
        binFa << "piszke";
        binFa << "alma";
        binFa << "ribizli";
        binFa << "ribizli";
        binFa << "ribizli";
        binFa << "alma";
        binFa << "banan";
    */

    binFa.kiir ();
    binFa.szabadit ();

    return 0;
}

 

 Egy asszociatív tárolós alternatíva

 

#include <iostream>
#include <string>
#include <map>

int
main ()
{
    std::string s;
    std::map<std::string, int> szoszmap;

    while (std::cin >> s)
        ++szoszmap[s];

    for (std::map<std::string, int>::iterator iter = szoszmap.begin(); iter != szoszmap.end(); ++iter)
        std::cout << iter->first << ", " << iter->second << std::endl;

    return 0;
}

 

Szólj hozzá!

Címkék: bináris fa asszociatív tároló

A bejegyzés trackback címe:

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

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.

Nincsenek hozzászólások.
süti beállítások módosítása