KIÍRÁS. - makestring("alma"^"korte\n"); > val it = "\"almakorte\\n\"" : string



Hasonló dokumentumok
KIÍRÁS AZ SML-BEN. Kiírás. Kiírás (folyt.) Kiírás (folyt.)

A számítástudomány alapjai. Katona Gyula Y. Számítástudományi és Információelméleti Tanszék Budapesti Műszaki és Gazdaságtudományi Egyetem

ABSZTRAKCIÓ FÜGGVÉNYEKKEL (ELJÁRÁSOKKAL)

Algoritmusok és adatszerkezetek gyakorlat 07

ÖSSZETETT ADATTÍPUSOK

Adatszerkezetek 7a. Dr. IványiPéter

B-fa. Felépítés, alapvető műveletek. Programozás II. előadás. Szénási Sándor.

FUNKCIONÁLIS PROGRAMOZÁS

Elemi adatszerkezetek

10. előadás Speciális többágú fák

LUSTA KIÉRTÉKELÉS, LUSTA LISTA

Hierarchikus adatszerkezetek

Fák Témakörök. Fa definíciója. Rekurzív típusok, fa adatszerkezet Bináris keresőfa, bejárások Bináris keresőfa, módosítás B-fa

2018, Funkcionális programozás

Információs Technológia

Absztrakt adatstruktúrák A bináris fák

Ugrólisták. RSL Insert Example. insert(22) with 3 flips. Runtime?

Amortizációs költségelemzés

Adatszerkezetek és algoritmusok

Adatszerkezetek I. 8. előadás. (Horváth Gyula anyagai felhasználásával)

BASH script programozás II. Vezérlési szerkezetek

file./script.sh > Bourne-Again shell script text executable << tartalmat néz >>

Funkcionális és logikai programozás. { Márton Gyöngyvér, 2012} { Sapientia, Erdélyi Magyar Tudományegyetem }

2019, Funkcionális programozás. 4. el adás. MÁRTON Gyöngyvér

file:///d:/okt/ad/jegyzet/ad1/b+fa.html

Aritmetikai kifejezések lengyelformára hozása

FUNKCIONÁLIS PROGRAMOZÁS

Keresőfák és nevezetes algoritmusaikat szemléltető program

Algoritmusok és adatszerkezetek gyakorlat 03 Oszd meg és uralkodj. Nagy

end function Az A vektorban elõforduló legnagyobb és legkisebb értékek indexeinek különbségét.. (1.5 pont) Ha üres a vektor, akkor 0-t..

Önszervező bináris keresőfák

Kupac adatszerkezet. A[i] bal fia A[2i] A[i] jobb fia A[2i + 1]

INFORMATIKA javítókulcs 2016

FUNKCIONÁLIS PROGRAMOZÁS GYAKORLAT JEGYZET

2. Milyen értéket határoz meg az alábbi algoritmus, ha A egy vektor?. (2 pont)

Bináris keresőfa. Felépítés, alapvető műveletek. Programozás II. előadás. Szénási Sándor

10. tétel. Adatszerkezetek és algoritmusok vizsga Frissült: január 28.

Kupac adatszerkezet. 1. ábra.

Egyirányban láncolt lista

Webprogramozás szakkör

van neve lehetnek bemeneti paraméterei (argumentumai) lehet visszatérési értéke a függvényt úgy használjuk, hogy meghívjuk

Tuesday, March 6, 12. Hasító táblázatok

Példa 30 14, 22 55,

Listák, szótárak, fájlok Listák, szótárak, fájlok

Logikai és funkcionális programozás funkcionális programozás modul

Alapok. tisztán funkcionális nyelv, minden függvény (a konstansok is) nincsenek hagyományos változók, az első értékadás után nem módosíthatók

2018, Funkcionális programozás

Ellenőrző kérdések. 36. Ha t szintű indexet használunk, mennyi a keresési költség blokkműveletek számában mérve? (1 pont) log 2 (B(I (t) )) + t

Gyakori elemhalmazok kinyerése

Rendezettminta-fa [2] [2]

A programozás alapjai előadás. [<struktúra változó azonosítók>] ; Dinamikus adatszerkezetek:

2019, Funkcionális programozás. 2. el adás. MÁRTON Gyöngyvér

2018, Funkcionális programozás

Dinamikus programozás vagy Oszd meg, és uralkodj!

Algoritmusok és adatszerkezetek II.

7 7, ,22 13,22 13, ,28

Az állományok kezelésére használt fontosabb parancsok

Generikus keresőfák Erlangban

Programozás I gyakorlat

Fa (Tree): csomópontok (nodes) halmaza, amelyeket élek (edges) kötnek össze, és teljesülnek az alábbi feltételek:

Feladat. Ternáris fa. Típusspecikáció. Reprezentáció. Absztrakt implementáció. Érdi Gerg EAF II. 4/3.

Adatszerkezetek I. 7. előadás. (Horváth Gyula anyagai felhasználásával)

Permutáció n = 3 esetében: Eredmény: permutációk száma: P n = n! romámul: permutări, angolul: permutation

Speciális adatszerkezetek. Programozás alapjai II. (8. ea) C++ Tömbök. Tömbök/2. N dimenziós tömb. Nagyméretű ritka tömbök

FUNKCIONÁLIS PROGRAMOZÁS ELŐADÁS JEGYZET

Szkriptnyelvek. 1. UNIX shell

Gelle Kitti Algoritmusok és adatszerkezetek gyakorlat - 07 Hasítótáblák

2018, Diszkrét matematika

FUNKCIONÁLIS PROGRAMOZÁS

Számláló rendezés. Példa

Rekurzió. Dr. Iványi Péter

Cekla. Készítette Doxygen Tue Sep :13:44

Algoritmuselmélet. 2-3 fák. Katona Gyula Y. Számítástudományi és Információelméleti Tanszék Budapesti Műszaki és Gazdaságtudományi Egyetem. 8.

Például számokból álló, egyszeresen láncolt lista felépítéséhez az alábbi struktúra definíciót használhatjuk:

Sztringkezelő függvények. A string típusú változók kezelése, használata és szerepük a feldolgozás során

Buborékrendezés: Hanoi Tornyai: Asszimptótikus fv.ek: Láncolt ábrázolás: For ciklussal:

2. Visszalépéses stratégia

Algoritmusok és adatszerkezetek II.

7. BINÁRIS FÁK 7.1. A bináris fa absztrakt adattípus 7.2. A bináris fa absztrakt adatszerkezet

HÁZI FELADAT PROGRAMOZÁS I. évf. Fizikus BSc. 2009/2010. I. félév

Adatszerkezetek Adatszerkezet fogalma. Az értékhalmaz struktúrája

Komputeralgebra Rendszerek

Táblázatok fontosabb műveletei 1

Lekérdezések az SQL SELECT utasítással

Adatszerkezetek Bevezetés Adatszerkezet Adatszerkezet típusok Műveletek Bonyolultság

Algoritmusok és adatszerkezetek gyakorlat 06 Adatszerkezetek

2. Visszalépéses keresés

A MAXIMUM-KUPACOL eljárás helyreállítja az A[i] elemre a kupactulajdonságot. Az elemet süllyeszti cserékkel mindaddig, amíg a tulajdonság sérül.

Algoritmizálás és adatmodellezés tanítása 1. előadás

ELTE SAP Excellence Center Oktatóanyag 1

file:///d:/apa/okt/ad/jegyzet/ad1/b+fa.html

Kifejezések. Kozsik Tamás. December 11, 2016

Rendezések. Összehasonlító rendezések

15. A VERSENYRENDEZÉS

A 2016/2017 tanévi Országos Középiskolai Tanulmányi Verseny első forduló javítási-értékelési útmutató. INFORMATIKA II. (programozás) kategória

Shannon és Huffman kód konstrukció tetszőleges. véges test felett

Bináris keresőfák. Adat : M Elemtip és Elemtip-on értelmezett egy lineáris rendezési reláció,

2019, Funkcionális programozás. 5. el adás. MÁRTON Gyöngyvér

Programozás alapjai II. (7. ea) C++ Speciális adatszerkezetek. Tömbök. Kiegészítő anyag: speciális adatszerkezetek

.Net adatstruktúrák. Készítette: Major Péter

Átírás:

KIÍRÁS Kiírás Kiírás 10-2 {TextIO.}prt : strg -> unit prt s = kiírja az s értékét a standard kimenetre, és azonnal kiüríti a puffert. {General.}makestrg : numtxt-> strg makestrg v = eredménye a v érték ábrázolása. {Meta.}prtVal : a -> a prtval e = kiírja az e kifejezés értékét a standard kimenetre pontosan úgy, ahogyan az SML értelmező írja ki a legfelső szten, és azonnal kiüríti a puffert. Eredményül visszaadja az e kifejezés értékét. Csak teraktív módban használható. Példák: - prt("alma"^"korte\n"; almakorte > val it = ( : unit - makestrg 5.8e 3; > val it = " 0.0058" : strg - prtval("alma"^"korte\n"; "almakorte\n"> val it = "almakorte\n" : strg - makestrg("alma"^"korte\n"; > val it = "\"almakorte\\n\"" : strg Megjegyzések. A kapcsos zárójelek { és } között opcionálisan megadható modulnév áll. Például {TextIO.}prt azt jelenti, hogy a függvény a TextIO modulban van defiálva, de az SML-értelmező a prt nevet rövid alakban is felismeri. numtxt = t real word word8 char strg

Kiírás (folyt. Kiírás 10-3 prtval-lal tetszőleges típusú érték íratható ki. További példák: - prtval (3, 5.0; (3, 5.0> val it = (3, 5.0 : t * real - prtval [#"A",#"Z",#":"]; [#"A", #"Z", #":"]> val it = [#"A", #"Z", #":"] : char list - datatype t = L B of t * t; > New type names: =t datatype t = (t,con B : t * t -> t, con L : t con B = fn : t * t -> t con L = L : t - val fa = B(B(B(L,B(L,B(L,B(B(L,L,L,L,B(L,L; > val fa = B(B(B(L, B(L, B(L, B(B(L, L, L, L, B(L, L : t - prtval fa; B(B(B(L, B(L, B(L, B(B(L, L, L, L, B(L, L> val it = B(B(B(L, B(L, B(L Kiírás (folyt. Kiírás 10-4 Az utolsó példában a kiírt sor túl hosszú lett, jó lenne eltörni a > jel előtt. Hogyan írathatunk ki egy újsor-jelet úgy, hogy az eredmény a fa érték maradjon? Például így, de ez elég körülményes: - let val res = prtval fa; val _ = prt "\n" res ; B(B(B(L, B(L, B(L, B(B(L, L, L, L, B(L, L > val it = B(B(B(L, B(L, B(L, B(B(L, L, L, L, B(L, L : t A before operátort az ilyen és hasonló dolgok kezelésére találták ki.

Szekvenciális kifejezés: before Kiírás 10-5 Az x before y kifejezés az ún. szekvenciális kifejezés egy változata. {General.}before : a * b -> a x before y = először az x-et, majd az y-t értékeli ki, eredménye az x értéke. Precedenciasztje 0. Példa before használatára: - prtval fa before prt "\n"; B(B(B(L, B(L, B(L, B(B(L, L, L, L, B(L, L > val it = B(B(B(L, B(L, B(L, B(B(L, L, L, L, B(L, L : t Az x before y-hoz hasonló a (x; y szekvenciális kifejezés, amely azonban az utolsó részkifejezésének az értékét adja eredményül. - (prt "A fa változó értéke =\n"; prtval fa before prt "\n"; A fa változó értéke = B(B(B(L, B(L, B(L, B(B(L, L, L, L, B(L, L > val it = B(B(B(L, B(L, B(L, B(B(L, L, L, L, B(L, L : t Kiírás (folyt. Kiírás 10-6 Hosszú lista, ill. egymásba skatulyázott adatszerkezetek esetén prtval (és maga az SML-értelmező is alapesetben csak az első 200 listaelemet, ill. legfeljebb 20 sztet ír ki. A hosszat a prtlength, a sztek számát a prtdepth frissíthető változó szabályozza. Mdkét érték felülírható. prtlength : t ref prtlength := 7;!prtLength; prtdepth : t ref prtdepth := 3;!prtDepth; Példák: - prtval [1,2,3,4,5,6,7,8,9,10] before prt "\n"; [1, 2, 3, 4, 5, 6, 7,...] > val it = [1, 2, 3, 4, 5, 6, 7,...] : t list - prtval fa before prt "\n"; B(B#, B# > val it = B(B#, B# : t Figyelem: a prtlength és a!prtlength kifejezések különböznek! - prtlength; > val it = ref 7 : t ref -!prtlength; > val it = 7 : t

Kiírás, szekvenciális kifejezés (folyt. Kiírás 10-7 Különböző típusú egyszerű értékeket alakítanak át füzérré a tostrg függvények: Char.toStrg : char -> strg Int.toStrg : t -> strg Real.toStrg : real -> strg Bool.toStrg : bool -> strg Word.toStrg : word -> strg Szekvenciális kifejezést felírhatunk a ; (pontosvessző alkalmazásával is. Az (x; y szekvenciális kifejezés, akárcsak az x before y, sztaktikai édesítőszer. Az (x; y ekvivalens az alábbi kifejezéssel: let val _ = x y NYOMKÖVETÉS, LISTÁK

Nyomkövetés: length (nem iteratív Nyomkövetés, listák 10-9 Az MOSML-ben nyomkövetés csak a program szövegébe beírt kiíró függvényekkel lehetséges. Példa: a length függvény két változatának kiértékelése A length naív változata fun length (_::xs = 1 + length xs length [] = 0 A length naív változata kiíró függvényekkel (félkövér szedéssel az eredeti szöveg látható fun length ((_ : t :: xs = prtval(1 + (prt " & "; prtval(length(prtval xs before prt " $ " before prt " #\n" length [] = (prt " * "; prtval 0 before prt " %\n" Nyomkövetés: lengthi (iteratív Nyomkövetés, listák 10-10 A length iteratív változata fun lengthi xs = let fun len (i, _::xs = len(i+1, xs len (i, [] = i len(0, xs A length iteratív változata kiíró függvényekkel (félkövér szedéssel az eredeti szöveg látható fun lengthi xs = let fun len (i, (_ : t :: xs = len((prt " "; prtval((prtval i before prt " $ " + 1, (prt " & "; prtval xs before prt "#\n" len (i, [] = (prt " * "; prtval i before prt " %\n" len(0, xs

Nyomkövetés: length egy alkalmazása Nyomkövetés, listák 10-11 length egy alkalmazása fun length ((_ : t :: xs = prtval(1 + (prt " & "; prtval(length(prtval xs before prt " $ " before prt " #\n" length [] = (prt " * "; prtval 0 before prt " %\n" length [1,2,3]; & [2, 3] & [3] & [] * 0 % 0 $ 1 # 1 $ 2 # 2 $ 3 # Nyomkövetés lengthi egy alkalmazása Nyomkövetés, listák 10-12 lengthi egy alkalmazása fun lengthi xs = let fun len (i, (_ : t :: xs = len((prt " "; prtval((prtval i before prt " $ " + 1, (prt " & "; prtval xs before prt "#\n" len (i, [] = (prt " * "; prtval i before prt " %\n" len(0, xs lengthi [1,2,3]; 0 $ 1 & [2, 3] 1 $ 2 & [3] 2 $ 3 & [] * 3 % # # #

Nyomkövetés: length és lengthi összehasonlítása Nyomkövetés, listák 10-13 length és lengthi kiértékelésének összehasonlítása length [1,2,3]; & [2, 3] & [3] & [] * 0 % 0 $ 1 # 1 $ 2 # 2 $ 3 # lengthi [1,2,3]; 0 $ 1 & [2, 3] 1 $ 2 & [3] 2 $ 3 & [] * 3 % # # # Korábban tárgyaltuk a nodes és depth függvényeket, valamt akkumulátort használó nodesa és deptha változatukat. A következő fóliákon e függvények kiértékelésének nyomkövetésére mutatunk megoldást. A szöveg olvashatóságát (sztenként növekvő behúzással javítjuk. A megfelelő számú szóköz beszúrására szolgál a tab függvény. A változó számú szóközből álló füzért paraméterként adjuk át, ezért olyan segédfüggvényeket vezetünk be, amelyeknek az őket meghívó függvényhez képest eggyel több paraméterük van. A függvények kiírást szolgáló részek nélküli szövegét félkövér szedéssel jelöljük. BINÁRIS FÁK, NYOMKÖVETÉS

Nyomkövetés: nodes (akkumulátort nem használ Báris fák, nyomkövetés 10-15 (* tab : strg -> strg tab i = a sorok behúzásához használandó i füzér szóközökkel kiegészítve * fun tab i = i ^ " " fun nodes f = let (* nodes0 : strg -> a tree -> t nodes0 i f = a csomópontok száma az f fáben; i a behúzáshoz használt füzér * fun nodes0 i (N(a, t1, t2 = (prt("\n" ^ i ^ "<"; prtval a : t; prt "> "; prtval(1 + nodes0 (tab i (prtval t2 before prt " *" + nodes0 (tab i (prtval t1 before prt " %" before prt "$ " before prt(" #\n" ^ i nodes0 i L = (prt("\n" ^ i; 0 nodes0 "" f Nyomkövetés: nodesa (akkumulátort használ Báris fák, nyomkövetés 10-16 fun nodesa f = let (* nodes0 i (f, n = n + a csomópontok száma f-ben; i a behúzáshoz használt füzér nodes0 : strg -> a tree * t -> t * fun nodes0 i (N(a, t1, t2, n = (prt("\n" ^ i ^ "<"; prtval a : t; prt "> "; nodes0 (tab i (prtval t1 before prt(" %\n" ^ (tab i, nodes0 (tab i (prtval t2 before prt(" *\n" ^ (tab i, prtval(n+1 before prt " $" before prt(" #" ^ i nodes0 i (L, n = (* (prt("\n" ^ i; n * n nodes0 "" (f, 0

nodes és nodesa alkalmazása hét csomópontból álló teljes fára Báris fák, nyomkövetés 10-17 f7 = N(1, N(2, N(4, L, L, N(5, L, L, N(3, N(6, L, L, N(7, L, L : t tree - nodes f7; - nodesa f7; <1> N(3, N(6, L, L, N(7, L, L * <1> N(2, N(4, L, L, N(5, L, L % <3> N(7, L, L * N(3, N(6, L, L, N(7, L, L * <7> L * 1 $ L % <3> N(6, L, L % $ 1 # N(7, L, L * N(6, L, L % 2 $ <6> L * <7> L % L % L * $ 1 # 3 $ # $ 3 # <6> L % N(2, N(4, L, L, N(5, L, L % L * 4 $ # # Folytatása a következő lapon. nodes és nodesa alkalmazása... (folyt. Báris fák, nyomkövetés 10-18 f7 = N(1, N(2, N(4, L, L, N(5, L, L, N(3, N(6, L, L, N(7, L, L : t tree (nodes f7 (nodesa f7 <2> N(5, L, L * <2> N(4, L, L % <5> L * N(5, L, L * L % 5 $ $ 1 # <5> L % N(4, L, L % L * <4> L * 6 $ # L % <4> L % $ 1 # L * $ 3 # 7 $ # # # $ 7 # > val it = 7 : t > val it = 7 : t

Nyomkövetés: depth (akkumulátort nem használ Báris fák, nyomkövetés 10-19 fun depth f = let (* depth0 i f = az f fa mélysége; i a behúzáshoz használt füzér depth0 : strg -> a tree -> t * fun depth0 i (N(a : t, t1, t2 = (prt("\n" ^ i ^ "<"; prtval a : t; prt "> "; prtval(1 + Int.max(depth0 (tab i (prtval t2 before prt " *", depth0 (tab i (prtval t1 before prt " %" before prt(" #\n" ^ i depth0 i L = (prt( "\n" ^ i ; 0 depth0 "" f Nyomkövetés: deptha (akkumulátort használ Báris fák, nyomkövetés 10-20 fun deptha f = let (* depth0 i (f, d = d + az f fa mélysége; i a behúzáshoz használt füzér depth0 : strg -> a tree * t -> t * fun depth0 i (N(a : t, t1, t2, d = (prt("\n" ^ i ^ "<"; prtval a : t; prt "> "; prtval(int.max(depth0 (tab i (prtval t2 before prt(" *\n" ^ (tab i, prtval(d+1 before prt " $ ", depth0 (tab i (prtval t1 before prt(" %\n" ^ (tab i, prtval(d+1 before prt " & " before prt(" #\n" ^ i depth0 i (L, d = (prt( "\n" ^ i ; d depth0 "" (f, 0

depth és deptha alkalmazása hét csomópontból álló teljes fára Báris fák, nyomkövetés 10-21 f7 = N(1, N(2, N(4, L, L, N(5, L, L, N(3, N(6, L, L, N(7, L, L : t tree - depth f7; - deptha f7; <1> N(3, N(6, L, L, N(7, L, L * <1> N(3, N(6, L, L, N(7, L, L * <3> N(7, L, L * 1 $ <7> L * <3> N(7, L, L * L % 2 $ 1 # <7> L * N(6, L, L % 3 $ <6> L * L % L % 3 & 1 # 3 # 2 # N(6, L, L % N(2, N(4, L, L, N(5, L, L % 2 & <6> L * 3 $ L % 3 & 3 # 3 # N(2, N(4, L, L, N(5, L, L % 1 & depth és deptha alkalmazása hét csomópontból álló teljes fára (folyt. Báris fák, nyomkövetés 10-22 Folytatás az előző lapról. f7 = N(1, N(2, N(4, L, L, N(5, L, L, N(3, N(6, L, L, N(7, L, L : t tree (depth f7 (deptha f7 <2> N(5, L, L * <2> N(5, L, L * <5> L * 2 $ L % <5> L * 1 # 3 $ N(4, L, L % L % <4> L * 3 & L % 3 # 1 # N(4, L, L % 2 # 2 & 3 # <4> L * 3 $ L % 3 & 3 # 3 # 3 # > val it = 3 : t > val it = 3 : t

BINÁRIS FÁK Egyszerű műveletek báris fákon (folyt. Báris fák 10-24 -ig beszámozza. Egy teljes báris fában mden csomópontból pontosan két él dul ki, és mden levelének ugyanaz a sztje. fulltree mélységű teljes báris fát épít, és a fa csomópontjait -től (* fulltree : t -> a tree fulltree n = n mélységű teljes fa * fun fulltree n = let fun ftree (_, 0 = L ftree (k, n = N(k, ftree(2*k, n-1, ftree(2*k+1, n-1 ftree(1, n reflect a fát a függőleges tengelye mentén tükrözi. (* reflect : a tree -> a tree reflect t = a függőleges tengelye mentén tükrözött t fa * fun reflect L = L reflect (N(v,t1,t2 = N(v, reflect t2, reflect t1

Lista előállítása báris fa elemeiből Báris fák 10-25 Mdhárom függvény báris fából listát állít elő. Abban különböznek egymástól, hogy a csomópontokban tárolt értékeket mikor veszik ki, és milyen sorrben járják be a részfákat: preorder először az értéket veszi ki, majd bejárja a bal, és azután a jobb részfát; order először bejárja a bal részfát, majd kiveszi az értéket, végül bejárja a jobb részfát; postorder először bejárja a bal, majd a jobb részfát, és utoljára veszi ki az értéket. Az akkumulátort nem használó változatok egyszerűek, érthetőek, de nem elég hatékonyak a @ operátor használata miatt. (* preorder : a tree -> a list preorder f = az f fa elemeek preorder sorrű listája * fun preorder L = [] preorder (N(v,t1,t2 = v :: preorder t1 @ preorder t2 (* order : a tree -> a list order f = az f fa elemeek order sorrű listája * fun order L = [] order (N(v,t1,t2 = order t1 @ (v :: order t2 (* postorder : a tree -> a list postorder f = az f fa elemeek postorder sorrű listája * fun postorder L = [] postorder (N(v,t1,t2 = postorder t1 @ postorder t2 @ [v] Lista előállítása báris fa elemeiből (folyt. Báris fák 10-26 Az akkumulátort használó változatok nehezebben érthetőek meg, de hatékonyabbak. (* preord : a tree * a list -> a list preord(f, vs = az f fa elemeek a vs lista elé fűzött, preorder sorrű listája * fun preord (L, vs = vs preord (N(v,t1,t2, vs = v::preord(t1, preord(t2,vs (* ord : a tree * a list -> a list ord(f, vs = az f fa elemeek a vs lista elé fűzött, order sorrű listája * fun ord (N(v,t1,t2, vs = ord(t1, v::ord(t2,vs ord (L, vs = vs (* postord : a tree * a list -> a list postord(f, vs = az f fa elemeek a vs lista elé fűzött, postorder sorrű listája * fun postord (N(v,t1,t2, vs = postord(t1, postord(t2, v::vs postord (L, vs = vs

Báris fa előállítása lista elemeiből: balpreorder Báris fák 10-27 Listát kiegyensúlyozott (balanced báris fává alakítanak a következő függvények: balpreorder, balinorder és balpostorder; a különbség közöttük most is a bejárási sorrben van. (* balpreorder: a list -> a tree balpreorder xs = az xs lista elemeiből álló, preorder bejárású, kiegyensúlyozott fa * fun balpreorder [] = L balpreorder (x::xs = let val k = length xs div 2 N(x, balpreorder(list.take(xs, k, balpreorder(list.drop(xs, k A hatékonyságot kisebb mértékben rontja, hogy List.take és List.drop egymástól függetlenül kétszer mennek végig a lista első felén. take és drop egyetlen függvénnyel: take ndrop Báris fák 10-28 Írjunk take ndrop néven olyan függvényt, amelynek egy xs listából és egy k egészből álló pár az argumentuma, és egy olyan pár az eredménye, amelynek első tagja a lista első k db eleme, második tagja pedig a lista többi eleme. (* take ndrop : a list * t -> a list * a list take ndrop(xs, k = olyan pár, amelynek első tagja xs első k db eleme, második tagja pedig xs maradéka * fun take ndrop (xs, k = let fun td (xs, 0, ts = (rev ts, xs td ([], _, ts = (rev ts, [] td (x::xs, k, ts = td(xs, k-1, x::ts td(xs, k, [] take ndrop felhasználása, nevezetesen az eredményül átadott pár miatt módosítani kell balpreorder felépítésén.

Báris fa előállítása lista elemeiből: balpreorder, újra Báris fák 10-29 Ez volt: fun balpreorder [] = L balpreorder (x::xs = let val k = length xs div 2 N(x, balpreorder(list.take(xs, k, balpreorder(list.drop(xs, k Ez lett: (* balpreorder: a list -> a tree balpreorder xs = az xs lista elemeiből álló, preorder... * fun balpreorder [] = L balpreorder (x::xs = let val k = length xs div 2 val (ts, ds = take ndrop(xs, k N(x, balpreorder ts, balpreorder ds Báris fa előállítása lista elemeiből Báris fák 10-30 (* balinorder: a list -> a tree balinorder xs = az xs lista elemeiből álló, order bejárású, kiegyensúlyozott fa * fun balinorder [] = L balinorder (xxs as x::xs = let val k = length xxs div 2 val ys = List.drop(xxs, k N(hd ys, balinorder(list.take(xxs, k, balinorder(tl ys (* balpostorder: a list -> a tree balpostorder xs = az xs lista elemeiből álló, postorder bejárású, kiegyensúlyozott fa * fun balpostorder xs = balpreorder(rev xs balinorder take ndrop-pal való defiálását meghagyjuk gyakorló feladatnak.

Elem törlése báris fából Báris fák 10-31 Adott értékű elemet rekurzív módszerrel megkeresni egyszerű feladat. Új elemet beszúrni sem nehéz: rekurzív módszerrel keresünk egy levelet, és ennek a helyére berakjuk az új értéket. Ha a fa rezve van, ügyelnünk kell arra, hogy a rezettség megmaradjon. Adott értékű elemet vagy elemeket rekurzív módszerrel kitörölni valamivel nehezebb: ha a törlő érték az éppen vizsgált részfa gyökerében van, a két részre széteső fa részfáit egyesíteni kell, miután a törlést a két részfán már végrehajtottuk. i v v jo Megtehetjük, hogy előbb egyesítjük a két részfát, majd az eredményül kapott fából töröljük az adott értékű elemet. Elem rekurzív törlése báris fából (folyt. Báris fák 10-32 A jo-nal egyesítjük a törlés hatására létrejövő két részfát: a bal részfát lebontja, és közben az elemeit egyesével berakja a jobb részfába. (* jo : a tree * a tree -> a tree jo(b, j = a b és a j fák egyesítésével létrehozott fa * fun jo (L, tr = tr jo (N(v, lt, rt, tr = N(v, jo(lt, rt, tr A remove rezetlen báris fából törli az i értékű elem összes előfordulását. (* remove : a * a tree -> a tree remove(i, f = i összes előfordulását törli f-ből * fun remove (i, L = L remove (i, N(v,lt,rt = if i<>v then N(v, remove(i,lt, remove(i,rt else jo(remove(i,lt, remove(i,rt

Báris keresőfák: blookup, bsert Báris fák 10-33 Rszert adott kulcsú elemet keresünk egy rezett báris fában, ehhez értékeket kell összehasonlítanunk egymással, ehhez a keresett kulcsnak egyenlőségi típusúnak kell lennie (a példában a strg típust használjuk. A függvények kivételt jeleznek, ha a keresett kulcsú elem ncs a keresőfában: exception Bsearch of strg. A blookup függvény adott kulcshoz tartozó értéket ad vissza: (* blookup : (strg * a tree * strg -> a blookup(f, b = az f fában a b kulcshoz tartozó érték * fun blookup (L, b = raise Bsearch("LOOKUP: " ^ b blookup (N((a,x, t1, t2, b = if b < a then blookup(t1,b else if a < b then blookup(t2, b else x Báris keresőfák: bupdate Báris fák 10-34 A bsert függvény egy új kulcsú elemet rak be egy rezett báris fába, ha még ncs benne: (* bsert : (strg * a tree * (strg * a -> (strg * a tree bsert(f, (b,y = az új (b,y kulcs-érték párral bővített f fa * fun bsert (L, (b,y = N((b,y, L, L bsert (N((a, x, t1, t2, (b,y = if b < a then N((a, x, bsert(t1, (b,y, t2 else if a < b then N((a, x, t1, bsert(t2, (b,y else (* a=b * raise Bsearch("INSERT: " ^ b A bupdate függvény meglévő kulcsú elembe új értéket ír be egy rezett báris fában: (* bupdate : (strg * a tree * (strg * a -> (strg * a tree bupdate(f, (b,y = az f fa, a b kulcshoz tartozó érték helyén az y értékkel * fun bupdate (L, (b,y = raise Bsearch("UPDATE: " ^ b bupdate (N((a,x, t1, t2, (b,y = if b < a then N((a,x, bupdate(t1, (b,y, t2 else if a < b then N((a,x, t1, bupdate(t2, (b,y else (* a=b * N((b,y, t1, t2 A függvények generikussá tételét meghagyjuk gyakorló feladatnak.

TÖBB MEGOLDÁS ELŐÁLLÍTÁSA VISSZALÉPÉSSEL n vezér a sakktáblán Több megoldás előállítása visszalépéssel 10-36 Hányféleképpen rakható n vezér a sakktáblára úgy, hogy ne üssék egymást? A vezéreket tartalmazó mezők sorának számát az egyes oszlopokon belül egy n hosszú sorvektor adott oszlophoz relt mezőjébe írt <= s < n szám adja meg. Példa n = 4 esetén: +---+---+---+---+ +---+---+---+---+ 0 ----> n-1 +---+---+---+---+ 0 +---+---+---+---+ +---+---+---+---+ V +---+---+---+---+ n-1 +---+---+---+---+ A sorvektort (egy egyre bővülő listával valósítjuk meg. Egy listához balról könnyű új elemeket fűzni, a táblát és a vezérek helyzetét leíró listát hossztengelye mentén tükrözzük....-+---+---+---+...-+---+---+---+ n-1 <---- 0...-+---+---+---+ 0...-+---+---+---+...-+---+---+---+ V...-+---+---+---+ n-1...-+---+---+---+

n vezér a sakktáblán (folyt. Azt, hogy az új vezért üti-e a már táblára rakott másik vezér, a sorvektor vizsgálatával dönthetjük el, amely tehát azt adja meg, hogy a listaelemek dexe által meghatározott oszlopban és a listaelem értéke által meghatározott sorban vezér van. 1. Az új vezér sorának száma, azaz az új listalem értéke nem fordulhat elő a lista már felépített részében. 2. Az új vezér átlós irányban sem lehet egy vonalban más vezérrel a táblán. Ez azt jelenti, hogy ha a sorvektort jelentő lista elejére az s sordexet akarjuk rakni, akkor az i-edik elemének az értéke, ha van ilyen eleme, nem lehet s-(i+1, ill. s+(i+1. 3. A következő példa segít megvilágítani az esetet. Több megoldás előállítása visszalépéssel 10-37 Ha a 2-es oszlopba és az s=1-es sorba akarjuk lerakni az új vezért, akkor az x-szel jelölt mezőket kell megvizsgálnunk. Az eddig létrehozott listának (sorvektornak két eleme van, ahol a lista fejének az dexe 0. A listafej értéke nem lehet s-1, sem s+1. A lista rekurzív algoritmussal dolgozható fel....-+---+---+ s...-+---+---+ n-1 <---- 0...-+---+---+---+ 0 x...-+---+---+---+ q...-+---+---+---+ V x...-+---+---+---+ n-1 x...-+---+---+---+ n vezér a sakktáblán: ütésben van -vizsgálat Több megoldás előállítása visszalépéssel 10-38 (* utesbenvan : t list -> bool utesbenvan zs = igaz, ha a (hd zs vezér ncs ütésben egyetlen (tl zs-beli vezérrel sem * fun utesbenvan [] = false utesbenvan (z::zs = let fun uv [] = false uv s1 s2 (r::rs = z = r orelse s1 = r orelse s2 = r orelse uv (s1-1 (s2+1 rs uv (z-1 (z+1 zs

n vezér a sakktáblán: egy megoldás előállítása Több megoldás előállítása visszalépéssel 10-39 exception Zsakutca (* vezerek0 : t -> t list vezerek0 n = a feladvány egy megoldása n vezér esetén * fun vezerek0 n = let fun vez0 z zs = if z = 0 andalso utesbenvan zs orelse z = n then raise Zsakutca else if length zs = n then rev zs else vez0 0 (z::zs handle Zsakutca => vez0 (z+1 zs vez0 0 [] n vezér a sakktáblán: több megoldás előállítása visszalépéssel Több megoldás előállítása visszalépéssel 10-40 (* vezerek : t -> t list list vezerek n = a feladvány összes megoldásának listája n vezér esetén * fun vezerek n = let fun vez0 z zs = if z = 0 andalso utesbenvan zs orelse z = n then raise Zsakutca else if length zs = n then [rev zs] else (vez0 0 (z::zs handle Zsakutca => [] @ (vez0 (z+1 zs handle Zsakutca => [] vez0 0 []

n vezér a sakktáblán: több megoldás előállítása listák listájával Több megoldás előállítása visszalépéssel 10-41 fun vezerek n = let fun vez0 z zs = if z = 0 andalso utesbenvan zs orelse z = n then [] else if length zs = n then [rev zs] else vez0 0 (z::zs @ vez0 (z+1 zs vez0 0 [] Ugyanez akkumulátor alkalmazásával: fun vezerek n = let fun vez0 z zs ws = if z = 0 andalso utesbenvan zs orelse z = n then ws else if length zs = n then rev zs :: ws else vez0 0 (z::zs (vez0 (z+1 zs ws vez0 0 [] []