Kezdőoldal » Számítástechnika » Programozás » Hogyan lehetne javítani...

Hogyan lehetne javítani ezeket a haskell compress és decompress függvényeket?

Figyelt kérdés

Adjuk meg azt a függvényt, amely egy listát úgy tömörít, hogy az egymás után szereplő azonos elemeket darabszám-elem párokká alakítja. Hasznos lehet a group függvény.


import Data.List


compress :: (Eq a, Integral b) => [a] -> [(b, a)]

compress l = zip ( length $ group l) ( head $ group l)


Példák:

compress "aaaabccaadeeee" == [(4,'a'), (1,'b'), (2,'c'), (2,'a'), (1,'d'), (4,'e')]

compress "oh hello!!" == [(1,'o'),(1,'h'),(1,' '),(1,'h'),(1,'e'),(2,'l'),(1,'o'),(2,'!')]

compress [] == []

compress [1,1,0,0,0,1,1,1] == [(2,1),(3,0),(3,1)]


Adjuk meg azt a függvényt, amely egy tömörített listából visszaállítja az eredetit. Hasznos lehet a replicate függvény.


decompress :: (Eq a, Integral b) => [(b, a)] -> [a]

decompress l = concat [replicate (fst x) (snd x) | x <- l]



Példák:

decompress [(4,'a'), (1,'b'), (2,'c'), (2,'a'), (1,'d'), (4,'e')] == "aaaabccaadeeee"

decompress [(1,'o'),(1,'h'),(1,' '),(1,'h'),(1,'e'),(2,'l'),(1,'o'),(2,'!')] == "oh hello!!"

decompress [] == []

decompress [(2,1),(3,0),(3,1)] == [1,1,0,0,0,1,1,1]



#Haskell #compress #decompress
2022. márc. 20. 17:11
 1/7 anonim ***** válasza:
0%

Egy byte-ban tárolod el a darabszámot is és az értéket is.

Plusz, ugye, ha az MSB 1 akkor tomoritett, ha 0 akkor nem.

Ha MSB = 1 akkor a darabszám lehet max plusz egy, hiszen egynél tobb a darabszám, ha már egyszer tomoritve van.

2022. márc. 20. 18:55
Hasznos számodra ez a válasz?
 2/7 anonim ***** válasza:
0%

01234567890123456


aaaaaaaaaaaaaaaaa


Ez egy byte-ban:


1 1110 001

2022. márc. 20. 19:00
Hasznos számodra ez a válasz?
 3/7 anonim ***** válasza:

a compress hibás

ha megnézed a zip típusát (:t zip), akkor látod, hogy az első paramétere "[a]" típusú (tehát valamilyen lista, mindegy, hogy mit tartalmaz, az "a" akár lehet szintén valamilyen lista típus is, de ez most lényegtelen)

te pedig egy Int típusú első paramétert adtál meg neki (:t length $ group l)

de ha ezt megpróbálod futtatni, akkor meg is kapod pontosan ezt a hibaüzenetet: "Couldn't match expected type `[a]' with actual type `Int'"

mindig azzal kell kezdeni, hogy mi a hibaüzenet, pontosan le van írva benne, hogy mi nem jó, de már nem egyszer javasoltam ezt szerintem..

ha az első példában megadott stringre futtatod a group függvényt, akkor ezt kapod: ["aaaa","b","cc","aa","d","eeee"]

mit kell ezzel csinálni? gyakorlatilag a lista minden tagjának meg kell feleltetni egy rendezett párt

az ilyen típusú leképezésekre van kitalálva a map függvényt


a decompressben szintén egy ilyen leképezést kell megcsinálni, csak a fordított irányban

a listás kifejezés helyett lehet használni map-et

tehát valahogy így nézne ki:

decompress = concat $ map ...

pl. az ilyen esetekben (amikor a concat és a map függvényeket egymás után kell használni) lehet használni a concatMap függvényt


egyébként meg teljesen felesleges kétszer ugyanazt a felbontást előállítani

pl. egy where-rel vagy let-in-nel ki lehet emelni egy tagot, amit többször is fel akarsz használni

pl.:


f :: [Char] -> [Char]

f x = (g ("akármi" ++ x)) ++ (h ("akármi" ++ x))


ehelyett


f :: [Char] -> [Char]

f x = (g y) ++ (h y) where y = ("akármi" ++ x)


vagy


f :: [Char] -> [Char]

f x = let y = ("akármi" ++ x) in (g y) ++ (h y)

2022. márc. 20. 22:05
Hasznos számodra ez a válasz?
 4/7 anonim ***** válasza:

module PointfreeStyle where


import Data.List (group, replicate)

import Control.Arrow ((&&&))


compress :: Eq a => [a] -> [(a, Int)]

compress = map (head &&& length) . group


decompress :: [(b, Int)] -> [b]

decompress = concatMap (uncurry $ flip replicate)


test, test1, test2, test3 :: Bool

test = test1 && test2 && test3

test1 = compress "Mississippi" == [('M', 1), ('i', 1), ('s', 2), ('i', 1), ('s', 2), ('i', 1), ('p', 2), ('i', 1)]

test2 = decompress [('M', 1), ('i', 1), ('s', 2), ('i', 1), ('s', 2), ('i', 1), ('p', 2), ('i', 1)] == "Mississippi"

test3 = (decompress . compress) "Mississippi" == "Mississippi"

2022. márc. 21. 15:31
Hasznos számodra ez a válasz?
 5/7 anonim ***** válasza:

Köszönöm szépen az inspirációt, kedves 3-as.


Megpróbáltam mindent besűríteni egy tömör modulba (ld. az előző válasz).


Tudom, most túl tömör lett, de érdemes részenként megnézni.

A lényeg és a talán elsőre nehezen érthető rész az &&& művelet.

Bár az Arrow-elmélet kicsit elfedi a lényeget, mivel az egy tágabb általánosítás, de a lényeg az, hogy a &&& az az alábbi műveletnek felel meg:


(&&&) :: (a -> b) -> (a -> c) -> a -> (b, c)


Given two functions, apply both to a single argument to form a pair. A specialised version of the Arrow &&&.


(succ &&& pred) 1 == (2,0)


Íme a dokumentációja:


[link]


Elérhető az alábbi modulból:

import Data.Tuple.Extra ((&&&))


ha esetleg nincs meg, lehet az Arrow modulból is importálni (ott is ugyanazt jelenti, csak egy általánosabb elmélet van mögötte, ami elsőre kicsit elfedi a lényeget, bár hosszú távon azt is mókás megismerni):


import Control.Arrow ((&&&))

2022. márc. 21. 15:42
Hasznos számodra ez a válasz?
 6/7 anonim ***** válasza:

Egy ábrában az &&& lényege:


[link]


Az ábrát magábanfoglaló tágabb témakör:


[link]


ennek 99%-a itt pont most nem kell, itt elég az ábrácskákat megnézni (abból is elég a &&& fogalma)

2022. márc. 21. 15:49
Hasznos számodra ez a válasz?
 7/7 anonim ***** válasza:

Kedves Kérdező,


A Te `zip`-es elgondolásod is javítható, bár fogalmilag kissé kevésbé ökonomikus, és talán erőforrás-igényesebb:


-------------------------------


module ZipSample where


import Data.List (group, replicate)


compress :: Eq a => [a] -> [(a, Int)]

compress l = zip (map head $ group l) (map length $ group l)


decompress :: [(b, Int)] -> [b]

decompress = concatMap (uncurry $ flip replicate)


test, test1, test2, test3 :: Bool

test = test1 && test2 && test3

test1 = compress "Mississippi" == [('M', 1), ('i', 1), ('s', 2), ('i', 1), ('s', 2), ('i', 1), ('p', 2), ('i', 1)]

test2 = decompress [('M', 1), ('i', 1), ('s', 2), ('i', 1), ('s', 2), ('i', 1), ('p', 2), ('i', 1)] == "Mississippi"

test3 = (decompress . compress) "Mississippi" == "Mississippi"


--------------------------


Látható, hogy a `&&&`-es megoldás a `zip`-es megoldással szemben azt teszi lehetővé, hogy a két függvényágból a ,,közös'' `map` és `group` függvény kiemelhető legyen:


- a `group` az elágazás előtti osztatlan közös függvényágba,

- a `map` pedig bele magába az egyik fő architekturális konstrukcióba (`concatMap`).

2022. márc. 21. 17:17
Hasznos számodra ez a válasz?

Kapcsolódó kérdések:




Minden jog fenntartva © 2025, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu

A weboldalon megjelenő anyagok nem minősülnek szerkesztői tartalomnak, előzetes ellenőrzésen nem esnek át, az üzemeltető véleményét nem tükrözik.
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!