Riješeno: provjeriti da li je lista sortirana

Naravno, ilustrovaću proces provere da li je lista u Haskelu sortirana ili ne. Ovo je uobičajena operacija u funkcionalnom programiranju i omogućava nam da osiguramo da elementi na listi slijede određeni redosljed, često od najmanjeg do najvećeg (ili obrnuto).

Haskell, kao statički otkucani, čisto funkcionalni programski jezik, pruža nam različite načine za rješavanje ovog problema. Dobro je poznat po svom snažnom zaključivanju tipa, što će nam značajno pomoći u ovom zadatku.

##

Problem: Provjera da li je lista sortirana

Kao Haskell programer, od vas se često traži da osigurate da sadržaj liste slijedi sortirani redoslijed. To znači da su elementi raspoređeni ili u rastućem ili opadajućem redoslijedu. Ovo je uobičajen zadatak koji se javlja kada se radi o korisničkim unosima, čitanju datoteka ili općenito upravljanju podacima.

Najjednostavniji način da provjerite da li je lista sortirana u Haskell-u je upoređivanje sa njegovom sortiranom verzijom. Haskell pruža ugrađenu funkciju sortiranje, koju možemo koristiti za sortiranje liste uzlaznim redoslijedom. Ako lista ostane ista nakon sortiranja, možemo sa sigurnošću zaključiti da je već sortirana. Hajde da vidimo kako to možemo učiniti:

import Data.List
isSorted :: (Ord a) => [a] -> Bool
isSorted xs = xs == sort xs

Ali, ova metoda nije optimalna jer zahtijeva punu vrstu liste koja troši vrijeme i resurse posebno za velike liste.

##

Rješenje: optimizirani kod

Lista je sortirana ako je za svaki par susjednih elemenata prvi manji ili jednak drugom. Da bismo ovo implementirali, koristit ćemo zipWith i sve funkcije u kombinaciji. Evo optimiziranog koda:

isSorted :: (Red a) => [a] -> Bool
isSorted xs = sve (neprometni (<=)) (zip xs (rep xs)) [/code] zip kombinuje dve liste u listu parova, dok rep preskače prvi element i vraća ostatak. uncurry primjenjuje binarni operator na par i sve provjerava da li uvjet vrijedi za sve elemente na listi. U našem slučaju uslov je da za svaki par prvi element bude manji ili jednak drugom.

##

Korak po korak objašnjenje koda

Optimizirani kod možemo dalje razumjeti tako što ćemo ga podijeliti na korake. Ideja je da se sekvencijalno provjerava svaki par elemenata na listi, i ako pronađemo bilo koji par gdje je prvi element veći od drugog, vraćamo False jer lista nije sortirana.

1. zip xs (rep xs) će uzeti listu [1,2,3,4] i pretvoriti je u listu parova [(1,2),(2,3),(3,4)]. Svaki par je u osnovi trenutni element i sljedeći element na listi.

2. Zatim koristimo sve funkcija koja uzima predikat (funkcija koja vraća Bool) i listu, i vraća True samo ako je predikat istinit za sve elemente na listi.

3. Naš predikat je ovdje (neprometni (<=)). uncurry uzima funkciju i tuple, i primjenjuje funkciju na elemente tuple. <= je naša funkcija ovdje, tako da bi uncurry (<=) bila funkcija koja uzima tuple (a, b) i vraća True ako je a <= b. Ovaj pristup nam pomaže da efikasno rešimo problem u linearnom vremenu, pružajući robusno i efikasno rešenje kada se bavimo potencijalno velikim listama. Što se tiče stila u Haskell-u, jezik promoviše pisanje čistog i sažetog koda. Stoga je dobar stil podijeliti i apstrahirati svoj kod u male funkcije koje se mogu sastaviti i razumne dijelove. Haskell visoko cijeni to što vam omogućava pisanje lijepog, jasnog i koda visokog nivoa.

Slični postovi:

Ostavite komentar