SI-möte #10, Programkonstruktion och Datastrukturer

Relevanta dokument
Övningsuppgifter #11, Programkonstruktion och datastrukturer

Programkonstruktion. Tentamen,

Programmeringsmetodik DV1, Programkonstruktion del 1 Tentamen,

Programkonstruktion. Tentamen,

Programkonstruktion. Tentamen,

Referentiell transparens. Programkonstruktion. Moment 10 Om sidoeffekter In/utmatning och imperativ programmering. Sidoeffekter.

Programkonstruktion. Moment 11 Om sidoeffekter In/utmatning och imperativ programmering. PKD 2011/12 moment 11 Sida 1 Uppdaterad

Omtentamen (del 1, 6 högskolepoäng) i Programkonstruktion och datastrukturer (1DL201)

Lösningsförslag för tentamen i Datastrukturer (DAT037) från

Programkonstruktion och datastrukturer. Moment 9 Om högre ordningens funktioner. PKD 2011/12 moment 9 Sida 1 Uppdaterad

Former av rekursion. Programkonstruktion. Moment 5 Mera om rekursion. Fakultetsfunktionen. Största gemensamma delare (repris!

Sökning. Viktiga algoritmer sökning och sortering. Sökning i en oordnad tabell:

Programkonstruktion och datastrukturer. Moment 9 Om högre ordningens funktioner. PKD 2010/11 moment 9 Sida 1 Uppdaterad

Programmering II (ID1019) :00-12:00

Exempeltenta GruDat 2002/2003

Dugga Datastrukturer (DAT036)

"Referentiell transparens"

Föreläsning 4 Datastrukturer (DAT037)

F6: Högre ordningens funktioner. Mönster för rekursion (1) Mönster för rekursion (1b) Mönster för rekursion (2) Högre Ordningens Funktioner

Programkonstruktion och datastrukturer. Formell verifiering eller hur man bevisar att program gör rätt utan att testa dem

Programkonstruktion och Datastrukturer

Föreläsning 6: Introduktion av listor

Tentamen TEN1 HI

Algoritmer, datastrukturer och komplexitet

Tenta (TEN3) i kursen 729G04 Programmering och diskret matematik 5 feb 2016, kl 14:00-18:00

6 Rekursion. 6.1 Rekursionens fyra principer. 6.2 Några vanliga användningsområden för rekursion. Problem löses genom:

Tentamen (del 2) (4 högskolepoäng) i Programkonstruktion och datastrukturer (1DL201)

Referentiell transparens. Programmeringsmetodik DV1 Programkonstruktion 1. Moment 10 Om sidoeffekter In/utmatning och imperativ programmering

TDDC74 Lab 04 Muterbara strukturer, omgivningar

Föreläsning 9 Datastrukturer (DAT037)

Föreläsning Datastrukturer (DAT036)

Tentamen TEN1 HI

Programkonstruktion och. Datastrukturer

Programmering II (ID1019) :00-17:00

Tillämpad Programmering (ID1218) :00-13:00

Datastrukturer, algoritmer och programkonstruktion (DVA104, VT 2015) Föreläsning 6

Anmälningskod: Lägg uppgifterna i ordning. Skriv uppgiftsnummer (gäller B-delen) och din kod överst i högra hörnet på alla papper

Programmering II (ID1019) :00-12:00

Programmeringsmetodik DV1 Programkonstruktion 1. Moment 9 Om högre ordningens funktioner. PK1&PM1 HT-06 moment 9 Sida 1 Uppdaterad

Programmering II (ID1019) :00-11:00

TDDI16 Datastrukturer och algoritmer. Algoritmanalys

Föreläsning Datastrukturer (DAT036)

Lösningsförslag till tentamen i EDA011, lördagen den 16 december 2006

Lösningsförslag till tentamen Datastrukturer, DAT037,

Föreläsning Datastrukturer (DAT037)

Funktionell programmering DD1361

Föreläsning 4 Datastrukturer (DAT037)

LÖSNINGSFÖRSLAG TENTAMEN PROGRAMMERING I ETT FUNKTIONELLT SPRÅK ML, 5P

Föreläsning 5 Innehåll. Val av algoritm och datastruktur. Analys av algoritmer. Tidsåtgång och problemets storlek

Föreläsning 7 Datastrukturer (DAT037)

Tentamen Programmeringsteknik II Inledning. Anmälningskod:

Föreläsning 5 Innehåll

Föreläsning 6 Datastrukturer (DAT037)

Föreläsning Datastrukturer (DAT036)

Tentamen Datastrukturer D DAT 035/INN960 (med mycket kortfattade lösningsförslag)

Algoritmer och effektivitet. Föreläsning 5 Innehåll. Analys av algoritmer. Analys av algoritmer Tidskomplexitet. Algoritmer och effektivitet

Föreläsning 8 Datastrukturer (DAT037)

Fredag 10 juni 2016 kl 8 12

Pythons standardbibliotek

Föreläsning 3-4 Innehåll. Diskutera. Metod. Programexempel med metod

729G04 Programmering och diskret matematik. Föreläsning 7

Föreläsning Datastrukturer (DAT037)

Föreläsning Datastrukturer (DAT036)

Föreläsning 3-4 Innehåll

Korsordlösare Sara Hedbrandh Strömberg Programkonstruktion VT 10 Inlämninsguppgift

Anmälningskod: Lägg uppgifterna i ordning. Skriv uppgiftsnummer (gäller B-delen) och din kod överst i högra hörnet på alla papper

Objektorienterad programmering D2

Objektorienterad programmering E. Algoritmer. Telefonboken, påminnelse (och litet tillägg), 1. Telefonboken, påminnelse (och litet tillägg), 2

TDIU01 - Programmering i C++, grundkurs

Erfarenheter från labben

Tentamen Datastrukturer (DAT036)

TDDC74 Programmering: Abstraktion och modellering Datortenta , kl 14-18

Uppgifter till tenta i 729G04 Programmering och diskret matematik. 17 december 2015, kl 14:00-18:00

Generiska konstruktioner. Kursbokens kapitel 13

Repetition i Python 3. Exemplen fac. Exemplen fac motivering. Exemplen fac i Python

Tabeller. Programkonstruktion. Moment 8 Om abstrakta datatyper och binära sökträd. Specifikationer för tabellfunktionerna. Operationer på tabellen

TDDC74 Programmering, abstraktion och modellering. Tentamen

Föreläsning 11 Datastrukturer (DAT037)

TDDC74 Programmering: Abstraktion och modellering Datortenta , kl 14-18

Tentamen Datastrukturer D DAT 036/DIT960

Tentamen'('Datastrukturer,'algoritmer'och'programkonstruktion.'

Tentamen: Programutveckling ht 2015

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 9 Jonas Lindgren, Institutionen för Datavetenskap, LiU

Objektorienterad Programkonstruktion. Föreläsning 9 30 nov 2016

Tentamen Datastrukturer D DAT 035/INN960

DD1320 Tillämpad datalogi. Lösning (skiss) till tenta 20 okt 2011

Sortering. Brute-force. Sortering Ordna element enligt relation mellan nyckelvärden

Några saker till och lite om snabbare sortering

Recap Mera om nya typer Kort Fält. Programmering. Sommarkurs Verónica Gaspes. IDE-sektionen.

Anmälningskod: Lägg uppgifterna i ordning. Skriv uppgiftsnummer (gäller B-delen) och din kod överst i högra hörnet på alla papper

Algoritmanalys. Inledning. Informationsteknologi Malin Källén, Tom Smedsaas 1 september 2016

Föreläsning 13. Rekursion

Programmering I Tobias Wrigstad fredag, 2009 augusti 28

Lösningsförslag till tentamen Datastrukturer, DAT037,

Arrayer (fält)

729G04 Programmering och diskret matematik

Sätt att skriva ut binärträd

if (n==null) { return null; } else { return new Node(n.data, copy(n.next));

Föreläsning 8 Datastrukturer (DAT037)

Transkript:

SI-möte #10, Programkonstruktion och Datastrukturer Lösngsförslag Elias Castegren & Kristia Ausmees elca7381@student.uu.se krau6498@student.uu.se 1. (* prtlist(l) TYPE: strg list -> unit PRE: () POST: () SIDE-EFFECTS: alla strängar i l skrivs ut på vars rad på termalen EXAMPLES: prtlist(["hej","på","dig"]) = () ("Hej\npå\ndig" skrivs ut på termalen) (* VARIANT: anta element i l fun prtlist([]) = () prtlist(f::r) = (prt (f ˆ "\n"); prtlist(r)); Två varianter med funktioner ur List-biblioteket: fun prtlist(l) = foldl (fn (s,_) => prt(s ˆ "\n")) () l; fun prtlist(l) = ((map (fn (s) => prt(s ˆ "\n")) l); ()); Notera att map-uttrycket ovan returnerar en unit-lista med lika många element som l. För att uppfylla typen i specifikationen returneras därför () efter att map-uttrycket beräknats. Det fns en byggd högre ordngens funktion i ML som heter app, med typen ( a -> unit) -> a list -> unit. Den applicerar en funktion utan eftervillkor på varje element i en lista och returnerar till sist unit. Med den hade man kunnat skriva funktionen så här: fun prtlist(l) = app (fn (s) => (prt(s ˆ "\n"))) l; 1

2. Med While-loop: Här använder vi en -sats för att öppna strömmarna och itiera en radräknar-referens i, sen loopar vi så länge vi te stöter på slutet på strömmen och avslutar med att stänga båda strömmarna. open TextIO; (* lenumbers(f) TYPE: strg->unit PRE: f är namnet på en fil som går att läsa POST: () SIDE-EFFECTS: En ström öppnas från filen f och en utström öppnas till filen f.numbered. Alla rader i f skrivs till f.numbered men med radnummer före. Alla strömmar stängs. EXAMPLES: lenumbers("fil") = () Om "fil" nhöll raderna Inte utan m ML-tolk! nehåller nu "fil.numbered" 1. Inte 2. utan 3. m 4. ML-tolk! fun lenumbers(f) = val s = openin(f) val os = openout(fˆ".numbered") val i = ref 1 (while(not (endofstream(s))) do (output(os, Int.toStrg(!i) ˆ ". " ˆ valof(putle(s))); i := (!i + 1)); closein(s); closeout(os)) 2

Med rekursion: Här använder vi en hjälpfunktion transferles som givet en ström och en utström kopierar strömmen och numrerar raderna. Huvudfunktionen öppnar strömmarna, skickar dem till transferles och stänger sedan strömmarna. open TextIO; fun lenumbers(f) = (* transferles(s, os, i) TYPE: stream * outstream * t -> unit PRE: s och os är läs- respektive skrivbara strömmar POST: () SIDE-EFFECTS: Alla rader i s skrivs till os, numrerade från i och uppåt (*VARIANT: Anta rader i s nan filslut fun transferles(s, os, i) = if endofstream(s) then () (output(os, Int.toStrg(i) ˆ ". " ˆ valof(putle(s))); transferles(s, os, i+1)) val s = openin(f) val os = openout(f ˆ ".numbered") (transferles(s, os, 1); closein(s); closeout(os)) 3

3. Poly/ML har get bibliotek för slumpade tal så för att testa funktionen kan man antgen skriva en funktion i stil med fun randomrange(a,b) = (a+b) div 2 eller använda någon annan ML-dialekt som har sluptalsmöjligheter (SML New Jersey och Moscow ML fungerar båda). Först skriver vi en hjälpfunktion som jämför två tal och skriver ut ifall det ena är större, mdre eller lika med det andra. Genom att ge den returtypen bool kan vi senare använda den i en if-sats för att avgöra om användaren har matat rätt gissng. (* comparenumbers(guess, correct) TYPE: t * t -> bool PRE: () POST: true om guess = correct, annars false SIDE-EFFECTS: skriver ut "Mdre!", "Storre!" eller "Ratt!" beroende på hur correct förhåller sig till guess. EXAMPLES: comparenumbers(45, 50) = false <"Storre!" skrivs ut på termalen> fun comparenumbers(guess, correct) = if guess > correct then (TextIO.prt "Mdre!\n"; false) if guess < correct then (TextIO.prt "Storre!\n"; false) (TextIO.prt "Ratt!\n"; true); Sedan skriver vi en funktion som låter användaren gissa ett givet tal (vi väntar alltså med slumpngen). (* guessnumber (ans) TYPE: t -> t PRE: () POST: ans SIDE-EFFECTS: låter användaren mata tal i termalen tills hon matar ans eller en tom rad. Instruktionerna "Mdre!", "Storre!", "Ratt!" och "Du måste skriva ett heltal!" skrivs till termalen vid behov. EXAMPLES: guessnumber (50) = 50 <Användaren får gissa tills hon matar 50 eller en tom rad> 4

(* VARIANT: Anta gissngar tills användaren matar ans fun guessnumber (ans) = val put = TextIO.putLe(TextIO.stdIn) val guess = Int.fromStrg(valOf(put)) if put = SOME "\n" then ans if guess = NONE then (prt "Du maste skriva ett heltal!\n"; guessnumber (ans)) if comparenumbers(valof(guess), ans) then ans guessnumber (ans) Slutligen skriver vi en funktion som slumpar fram ett tal och sätter igång spe (genom att anropa hjälpfunktionen guessnumber ). (* guessnumber(n) TYPE: t -> t PRE: n>0 POST: ett slumpat tal mellan 0 och n SIDE-EFFECTS: "Gissa ta!" skrivs ut till termalen. Sedan får användaren spela ett parti "gissa ta", där svaret är mellan 0 och n, i termalen. EXAMPLES: guessnumber(100) = 50 <Användaren får gissa tal tills hon gissar rätt eller ger upp> fun guessnumber(max) = val rand = randomrange(0, max) (TextIO.prt("Gissa ta!\n");guessnumber (rand)) 5

Här följer en helt imperativ version av guessnumber, som blir några rader kortare mest för att det är färre fun- och -satser. (* guessnumber(n) TYPE: t -> t PRE: n>0 POST: ett slumpat tal mellan 0 och n SIDE-EFFECTS: Skriver ut "Gissa ta!" och låter sedan användaren mata tal i termalen tills hon gissar rätt eller matar en tom rad. Instruktionerna "Mdre!", "Storre!", "Ratt!" och "Du måste skriva ett heltal!" skrivs till termalen vid behov. EXAMPLES: guessnumber(100) = 50 <Användaren får gissa tills hon matar 50 eller en tom rad> fun guessnumber(n) = val ans = randomrange(0,n) val put = ref NONE val guess = ref NONE val contue = ref true (prt "Gissa ta!\n"; while (!contue) do (put := TextIO.putLe(TextIO.stdIn); guess := Int.fromStrg(valOf(!put)); if!put = SOME "\n" then contue := false if!guess = NONE then prt "Du maste skriva ett heltal!\n" if valof(!guess) > ans then prt "Mdre!\n" if valof(!guess) < ans then prt "Storre!\n" (prt "Ratt!\n"; contue := false) ); ans) 6

4. 7

5. 8

6. Ett bomialträd med rang n har 2 n noder. En bomial heap nehåller alltså t 0 2 0 + t 1 2 1 + t 2 2 2 + + t m 2 m noder, där t i är ett eller noll beroende på om heapen har ett träd med rang i eller te. Ett bärt tal d m d m 1 d m 2... d 0 blir decimalt d 0 2 0 + d 1 2 1 + d 2 2 2 + + d m 2 m där d i är ett eller noll. Anta noder i ett bomialträd är alltså detsamma som ett bärt tal enligt ovan där en etta betyder att heapen har ett träd med motsvarande rang. 1. (52) 10 = (110100) 2 - rangerna hos träden i heapen är alltså 2, 4 och 5 (dex från höger för ettorna i det bära ta) 2. (53) 10 = (110101) 2 - rangerna är 0, 2, 4 och 5 3. (127) 10 = (1111111) 2 - heapen nehåller träd av alla ranger mellan 0 och 7 4. (128) 10 = (10000000) 2 - heaper nehåller ett träd av rang 8 När anta noder är 2 k 1 måste man slå ihop k stycken träd om man lägger ett nytt element (se övergången från 127 till 128 noder ovan). Det tar alltså längre tid att lägga nya element när man har många ettor i följd i den bära representationen av anta noder. 7. heapsort(l) : t list t list 1. Skapa en tom max-heap H 2. Sätt alla element i l i H, ett och ett 3. Ta ut det största elementet ur H och lägg det först i en lista l 4. Är H tom? Gå tillbaka till steg 3, annars returnera l Antag att listan som ska sorteras har l element. Vi gör först l stycken sättngar och sen l stycken extrahergar (båda operationerna med komplexitet Θ(log n), där n är anta noder i heapen). Den totala komplexiteten blir alltså l Θ(log l ) + l Θ(log l ) = Θ( l log l ) Med andra ord är den jämförbar med mergesort och quicksort! 9

En ML-implementation med en m-heap följer nedan. Heapimplementationen kommer från föreläsngarna och fns att hämta från kurshemsidan. (* sort(l) TYPE: t list -> t list PRE: () POST: l sorterad EXAMPLES: sort([5,3,4,2,1]) = [1,2,3,4,5] fun sort(l) = (* extractall(h) TYPE: boheap -> t list PRE: h uppfyller varianten för bomiala m-heapar POST: en sorterad lista med alla element i h EXAMPLES: sort({en heap med elementen <3,4,5>}) = [3,4,5] (* VARIANT: Anta element i heapen h fun extractall(h) = if null(h) then [] val (e, h ) = extractm(h) e::extractall(h ) end val H = foldr (fn(e, h) => sert(h, e)) [] l extractall(h) Tänk på att heapen är defierad som: type boheap = botree list En tom heap är alltså detsamma som en tom lista (se foldr-anropet). Därför kan man också använda listfunktioner som null för att se om en heap är tom. 10