Használható segédanyagok: Haskell könyvtárainak dokumentációja, a tárgy honlapja és a BE-AD rendszerbe feltöltött beadandók. Ha bármi kérdés, észrevétel felmerül, azt a gyakorlatvezetőnek kell jelezni, NEM a mellettünk ülőnek!
A feladatok egymásra épülnek ezért érdemes ezeket a megadásuk sorrendjében megoldani, de legalább megérteni az aktuális feladatot megelőző feladatokat!
A feladatunk az lesz, hogy definiáljuk egy egyszerű tömörítést.
Az általunk megvalósítandó tömörítéshez kódokat fogunk meghatározni. A kódokat az előfordulási gyakoriságuk alapján fogjuk meghatározni úgy, hogy a leggyakrabban előforduló elemhez a legrövidebb, a legritkábbhoz pedig az egyik leghosszabb kód fog tartozni. Természetesen az mindig a szövegtől függ, hogy az egyes elemekhez milyen kódokat rendelünk.
A tömörítéshez szükségünk lesz egy táblára, amely tartalmazza a szöveg elemeit és a hozzájuk tartozó tömörítőkódokat. Ezt a táblát kell majd felépíteni és használni a tömörítéshez.
A tömörítőkódokat tartalmazó tábla reprezentációja a következő:
Bit
típusú elemek sorozatával definiálunk, amely értékeit a Zero
és One
konstruktorok képezik.Például:
A tömörítéshez használt kódok előállítása egy fával szemléltethető, melyet a gyökerétől kezdünk felépíteni, majd a jobb részfát bővítjük folyamatosan addig, amíg minden elemhez nem rendeltünk egy tömörítő kódot. A tömörítéshez fontos lesz, hogy tömörítő kódok meghatározásához a szövegben az elemek előfordulási gyakoriságuk sorrendjében legyenek megadva, azaz legelől a leggyakoribb, stb.
Nézünk egy egyszerű példát és a példán keresztül a tömörítési lépéseket nagyvonalakban.
Adott az "abrakadabra"
szövegünk. Elsőként az ehhez tartozó tömörítőkódokat szeretnénk előállítani, az egyes karakterek előfordulásának a gyakoriságának megállapításával.
A karakterek előfordulási gyakorisága:
'a' -> 5
'b' -> 2
'r' -> 2
'd' -> 1
'k' -> 1
A nekik megfelelő tömörítőkódok:
'a' -> [Zero]
'b' -> [One, Zero]
'r' -> [One, One, Zero]
'd' -> [One, One, One, Zero]
'k' -> [One, One, One, One]
Megjegyzés: A kódok az alábbi bináris fa alapján olvashatóak ki.
Ha vesszük a fa gyökere és a keresett karakter közötti útvonalat, az élek címkéiről leolvasható az egyes karakterekhez tartozó tömörítőkód.
Miután megállapítottuk a tömörítőkódokat a szövegben előforduló összes karakterhez, a szöveget tömöríteni tudjuk Bit
értékek sorozatává.
a -> [Zero]
b -> [One, Zero]
r -> [One, One, Zero]
a -> [Zero]
k -> [One, One, One, One]
a -> [Zero]
d -> [One, One, One, Zero]
a -> [Zero]
b -> [One, Zero]
r -> [One, One, Zero]
a -> [Zero]
Tehát az eredeti szövegünk tömörített változata a következő lesz.
[Zero,One,Zero,One,One,Zero,Zero,One,One,One,One,Zero,One
,One,One,Zero,Zero,One,Zero,One,One,Zero,Zero]
Mivel már tömöríteni tudunk és megalkottuk a megfelelő tömörítési szótárt, ez felhasználható a kitömörítési folyamathoz.
A továbbiakban ezeket a tömörítési és kitömörítési lépéseket nézzük meg részletesebben.
Adjuk meg azt a függvényt, amely az adott szövegben megadja az egyes karakterek gyakoriságát! A gyakoriságokat a karakterek szerinti lexikografikus sorrendben adjuk meg! Az eredményben minden karakterhez csak egyetlen bejegyzés tartozhat!
Adjuk meg azt a függvényt, amely rendezi a szövegben található karaktereket azok előfordulásának gyakorisága szerint! Az eredmény szövegében a leggyakrabban előforduló karakter szerepeljen legelől, majd követik csökkenő sorrendben a továbbiak! Azonos gyakorisággal bíró karakterek közt a lexikografikus sorrend döntsön. Az eredményben ne ismétlődjenek karakterek!
Adjuk meg azt a segédfüggvényt, amely megadja a kiosztható kódok közül a következőt az előző kód alapján!
Adjuk meg azt a függvényt, mely megadja a kiosztható kódok végtelen sorozatát!
Adjuk meg azt a függvényt, amely egy adott szövegből előállítja az egyes karakterekhez tartozó tömörítőkódokat! Az eredmény legyen egy asszociációs lista (rendezett kulcs-érték párok listája, ahol a karakter a kulcs)!
Fontos:
A leggyakrabban előforduló karakter tömörítő kódja egy darab Zero
lesz;
Minden további tömörítő kód Zero
értékkel zárul, pl. [One, Zero]
;
Egyedüli kivételt a legritkábban előforduló elem jelent, mert az csupa egyesekből fog állni, pl. [One, One, One]
!
Definiáljuk a táblában kereső függvényt, amely egy karakter és egy tábla felhasználásával megadja a karakterhez rendelt tömörítő kódot! Feltételezhetjük, hogy a keresett karakterhez mindig tartozik bejegyzés a táblázatban.
Készítsük el a szöveget kóddá alakító függvényt, amely minden egyes karaktert helyettesít a neki megfelelő tömörítőkódot! A függvény a paraméterül kapott szöveg alapján mindig elkészíti a tömörítéshez használt táblát is
Adjuk meg azt a keresőfüggvényt, amely tábla felhasználásával megadja a kódsorozat elejéhez illeszkedő kódú karaktert! Feltételezzük, hogy ez minden esetben megadható!
Készítsük el azt a függvényt, amely egy tömörített kódsorozatból egy tábla segítségével visszafejti az eredeti szöveget.
B szakirány:
T szakirány: