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

Relevanta dokument
Programmeringsmetodik DV1 Programkonstruktion 1. Moment 4 Om rekursion. PK1&PM1 HT-06 moment 4 Sida 1 Uppdaterad

Summera godtyckligt antal tal. Programkonstruktion. Moment 4 Om rekursion. Fullständigt resonemang för summeringen. Analys av summeringsproblemet

Programkonstruktion och datastrukturer. Moment 3 Rekursion och listor. PKD 2012/13 moment 3 Sida 1 Uppdaterad

Programkonstruktion och Datastrukturer

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

FÖRELÄSNING 2, TDDC74, VT2018 BEGREPP PROBLEMLÖSNING MED HJÄLP AV FALLANALYS PROBLEMLÖSNING MED HJÄLP AV REKURSION

SI-möte #10, Programkonstruktion och Datastrukturer

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

BEGREPP HITTILLS FÖRELÄSNING 2 SAMMANSATTA UTTRYCK - SCHEME DATORSPRÅK

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

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. Moment 9 Om högre ordningens funktioner. PKD 2011/12 moment 9 Sida 1 Uppdaterad

Föreläsning 5: Kardinalitet. Funktioners tillväxt

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

Algoritmer, datastrukturer och komplexitet

Introduktion till programmering SMD180. Föreläsning 4: Villkor och rekursion

Programkonstruktion. Tentamen,

Algoritmer och datastrukturer H I HÅKAN S T R Ö M B E R G N I C K L A S B R A N D E F E L T

Introduktion till programmering SMD180. Föreläsning 9: Tupler

Algoritmer, datastrukturer och komplexitet

Föreläsning 9: Talteori

Övningshäfte 2: Induktion och rekursion

"Referentiell transparens"

Programkonstruktion. Tentamen,

Introduktion till programmering D0009E. Föreläsning 5: Fruktbara funktioner

Tentamen i Introduktion till programmering

Några inbyggda funktioner (med resultat!) Introduktion till programmering D0009E. Föreläsning 4: Villkor och rekursion. Modulus-operatorn.

DD1361 Programmeringsparadigm. Carina Edlund

Tabeller. Programkonstruktion. Moment 8 Om abstrakta datatyper och binära sökträd. Implementering av tabellen. Operationer på tabellen

Tentamen i kurserna Beräkningsmodeller (TDA181/INN110) och Grundläggande Datalogi (TDA180)

Föreläsning 13. Rekursion

Tommy Färnqvist, IDA, Linköpings universitet. 2 Rekursion i C Implementation av rekursion Svansrekursion En till övning...

Rekursion. Koffman & Wolfgang kapitel 5

Multipel tilldelning. Introduktion till programmering D0009E. Föreläsning 6: Iteration. while-satsen. Kom ihåg. Snurror kontra rekursion

Rekursion och induktion för algoritmkonstruktion

Föreläsning 4 Datastrukturer (DAT037)

Föreläsningsanteckningar F6

Föreläsning 9: Talteori

Föreläsning 7 Innehåll. Rekursion. Rekursiv problemlösning. Rekursiv problemlösning Mönster för rekursiv algoritm. Rekursion. Rekursivt tänkande:

SCB :-0. Uno Holmer, Chalmers, höger 2 Ex. Induktiv definition av lista. // Basfall

Föreläsning 6: Introduktion av listor

TDDC74 Programmering: Abstraktion och modellering Dugga 1, kl 14-16

Algoritmanalys. Genomsnittligen behövs n/2 jämförelser vilket är proportionellt mot n, vi säger att vi har en O(n) algoritm.

Programmeringsmetodik DV1 Programkonstruktion 1. Moment 8 Om abstrakta datatyper och binära sökträd

Introduktion till programmering SMD180. Föreläsning 5: Fruktbara funktioner

Algoritmer, datastrukturer och komplexitet

Procedurer och villkor. Rekursiva procedurer. Exempel: n-fakultet

Procedurer och villkor

C++ Funktioner 1. int summa( int a, int b) //funktionshuvud { return a+b; //funktionskropp } Värmdö Gymnasium Programmering B ++ Datainstitutionen

Introduktion till algoritmer - Lektion 4 Matematikgymnasiet, Läsåret Lektion 4

Programkonstruktion. Tentamen,

public static void mystery(int n) { if (n > 0){ mystery(n-1); System.out.print(n * 4); mystery(n-1); } }

Föreläsning 7: Syntaxanalys

Uppgift 1 ( Betyg 3 uppgift )

Programmeringsmetodik DV1, Programkonstruktion del 1 Tentamen,

Rekursion och induktion för algoritmkonstruktion

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

Föreläsning 6: Induktion

Sökning och sortering

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

Introduktion till formella metoder Programmeringsmetodik 1. Inledning

Talteori (OBS en del frågor gäller diofantiska ekvationer och de tas inte upp från och med hösten 2012)

Programmeringsteknik med C och Matlab

Produktionsplanering. Programkonstruktion. Ett programutvecklingsexempel. Programutvecklingsprocessen. Exempel produktregister. 2.

Tentamen. Datalogi I, grundkurs med Java 10p, 2D4112, Lördagen den 30 november 2002 kl , salar E33, E34

Träd, binära träd och sökträd. Koffman & Wolfgang kapitel 6, avsnitt 1 4

Dugga Datastrukturer (DAT036)

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

Programkonstruktion och datastrukturer. Moment 5 Om generella datastrukturer och träd. PKD 2011/12 moment 5 Sida 1 Uppdaterad

Lösning av några vanliga rekurrensekvationer

Objektorienterad programmering Föreläsning 8. Copyright Mahmud Al Hakim Agenda (halvdag)

Dekomposition och dynamisk programmering

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

Lennart Rolandsson, Uppsala universitet, Ulrica Dahlberg och Ola Helenius, NCM

Programkonstruktion och datastrukturer. Moment 4 Programmeringsmetodik och programvaruteknik. PKD 2011/12 moment 4 Sida 1 Uppdaterad

Programkonstruktion och datastrukturer. Moment 4 Programmeringsmetodik och programvaruteknik. PKD 2010/11 moment 4 Sida 1 Uppdaterad

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

TDDC74 Programmering, abstraktion och modellering DUGGA 1

TDDC74 Programmering: Abstraktion och modellering Tentamen, lördag 27 augusti 2016, kl 8 12

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

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

Johan Karlsson Datavetenskap för teknisk kemi, 10p, moment 1 Datavetenskap Umeå Universitet. Tentamen

Tentamen 1 (6 högskolepoäng) i Programkonstruktion och datastrukturer (1DL201)

Programmering II (ID1019) :00-11:00

Föreläsning 4 Datastrukturer (DAT037)

Tentamen OOP

Tommy Färnqvist, IDA, Linköpings universitet

Föreläsning 5. Rekursion

Våra enkla funktioner eller procedurer

Exempel: Förel Rekursion III Nr 14. Uno Holmer, Chalmers,

Programkonstruktion och datastrukturer. Moment 6 Om generella datastrukturer och träd. PKD 2012/13 moment 6 Sida 1 Uppdaterad

Föreläsning 11: Rekursion

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

Tentamen i kurserna Beräkningsmodeller (TDA181/INN110) och Grundläggande Datalogi (TDA180)

Övningshäfte 1: Induktion, rekursion och summor

Språket Python - Del 1 Grundkurs i programmering med Python

Typsystem. Typsystem... Typsystem... Typsystem... 2 *

Föreläsning 5 Innehåll

Typsystem. DA2001 (Föreläsning 23) Datalogi 1 Hösten / 19

Transkript:

Programkonstruktion Moment 5 Mera om rekursion Former av rekursion enkel rekursion ett rekursivt anrop. fullständig rekursion argumenten (varianten) kan mska olika många steg i det rekursiva anropet. multipel rekursion flera rekursiva anrop. ömsesidig rekursion flera funktioner anropar varandra rekursivt. kapslad rekursion rekursiva anrop i argumenten till andra rekursiva anrop. Obs: Att se varianten som gräns för anta rekursiva anrop går te vid multipel eller kapslad rekursion. Not: Med flera rekursiva anrop menas anrop som faktiskt utförs. Om flera anrop fns men är i olika grenar av if-uttryck så att bara ett kan utföras vid ett givet tillfälle så är det te multipel rekursion. PK 28/9 moment 5 Sida 1 Uppdaterad 28-1-15 PK 28/9 moment 5 Sida 2 Uppdaterad 28-1-15 Fakultetsfunktionen (* fact n Type: t->t Pre: n >= Post: n-fakultet (n!) Ex.: fact 4 = 24 fact 6 = 72 fact 12 = 47916 *) fun fact = 1 fact n = n*fact(n-1) fact växer fort fact 13 ger overflow på stitutionens masker. Denna typ av rekursion när man har ett rekursivt anrop och varianten mskar ett steg i taget kallas enkel rekursion. Största gemensamma delare (repris!) Största gemensamma delaren (gcd) till 126 och 168 Start. Är n=? Nej. Ja. Stopp. Låt r vara resten när m delas med n. Låt m vara n. Låt n vara r. m n r 126 168 168 126 42 126 42 126 42 PK 28/9 moment 5 Sida 3 Uppdaterad 28-1-15 PK 28/9 moment 5 Sida 4 Uppdaterad 28-1-15 gcd i ML (repris!) (* gcd(m,n) Type: t*t->t Pre: m,n>= Post: Största gemensamma delaren till m och n Ex.: gcd(126,168) = 42 *) fun gcd(m,) = m gcd(m,n) = gcd(n, m mod n) Varianten kan mska olika mycket i varje steg fullständig rekursion. Tornen i Hanoi A B C Problem: Flytta alla skivor från A till C. Regler: En skiva i taget får flyttas Endast den översta skivan får flyttas. En skiva får bara ligga ovanpå större skivor. Uppgift: Skriv ett program för att beräkna hur flyttngen skall gå till (givet ett visst antal brickor). (Ett exempel på ett planergsproblem) PK 28/9 moment 5 Sida 5 Uppdaterad 28-1-15 PK 28/9 moment 5 Sida 6 Uppdaterad 28-1-15

Lösng av Hanoi-problemet Vi skall flytta n brickor. Antag att vi vet hur man skall flytta n-1 brickor. Flytta n-1 brickor från A till B (via C). Flytta den sista brickan från A till C. Flytta n-1 brickor från B till C (via A). Klart!! När man löser delproblemen är det te säkert att till eller via - pnarna är tomma, men i så fall ligger det större brickor på dem. Denna lösng ger direkt ett naturligt program i ML. Observera att lösngen kräver två rekursiva anrop (multipel rekursion). Hanoi-problemet i ML (* hanoi(n,from,via,to) Type: t*strg*strg*strg->strg Pre: n>=. from, via och to är olika strängar. Post: En sträng som beskriver hur man skall flytta n brickor i Hanoi-spe från pne from till pne to med hjälp av pne via. Ex.: hanoi(,"a","b","c") = "" hanoi(1,"a","b","c") = "A->C " hanoi(2,"a","b","c") = "A->B A->C B->C " *) fun hanoi(,_,_,_) = "" hanoi(n,from,via,to) = hanoi(n-1,from,to,via) ^ from ^ "->" ^ to ^ " " ^ hanoi(n-1,via,from,to) PK 28/9 moment 5 Sida 7 Uppdaterad 28-1-15 PK 28/9 moment 5 Sida 8 Uppdaterad 28-1-15 Mönstermatchng Problem: Man vill se om en sträng passar mot ett teckenmönster (matchar). I detta exempel är ett mönster en följd av tecken där? betyder godtyckligt tecken * betyder en följd av noll eller flera godtyckliga tecken. Exempel: "K*a", "K?ll? Ank?" och "Kalle*" matchar "Kalle Anka" "K*k", "K?alle Anka" och "??" matchar te. Problemuppdelng för matchng Är mönstret tomt eller ej? a) Ja då måste strängen också vara tom. b) Nej dela upp mönstret i första tecken och resten Välj alternativ beroe på första tecken a) "?" matcha resten av strängen med resten av mönstret. b) "*" matcha stjärnan (hur?!?) c) Annat tecken kolla att strängen börjar med det tecknet och matcha resten av strängen mot resten av mönstret. Skriv en funktion som kan avgöra om ett mönster matchar strängen eller ej! PK 28/9 moment 5 Sida 9 Uppdaterad 28-1-15 PK 28/9 moment 5 Sida 1 Uppdaterad 28-1-15 Matcha stjärnan Stjärnan matchar ett godtyckligt (kl. ) antal tecken. Ett mönster som börjar med en stjärna matchar alltså en sträng om resten av mönstret matchar strängen med början på godtycklig plats. Man får pröva i början av strängen och sedan prova ett tecken framåt i taget (sökng). T.ex. sträng: "abcd", mönster "*cd". Matchar "abcd" mönstret "cd"? Nej. Matchar "bcd" mönstret "cd"? Nej. Matchar "cd" mönstret "cd"? Ja! (Här matchade alltså stjärnan de två tecknen "ab".) Problemuppdelng för matchng av stjärna Har vi provat hela strängen? a) Ja Mönstret matchar te b) Nej. Matchar strängen vid given position resten av mönstret? a) Ja. Klart. b) Nej. Prova med nästa position. Nu kan vi skriva kod direkt från problemuppdelngarna! Vi får en huvudfunktion och en hjälpfunktion. PK 28/9 moment 5 Sida 11 Uppdaterad 28-1-15 PK 28/9 moment 5 Sida 12 Uppdaterad 28-1-15

Funktionen match (* match(s,pattern) Type: strg*strg->bool Pre: (gen) Post: true om s matchar pattern, false annars. Ex: match("abc","a?c") = true match("abc","*c") = true match("abc","?c") = false *) (* Variant: size pattern *) fun match(s,"") = s = "" match(s,pattern) = case Strg.sub(pattern,) of #"*" => matchstar(s,strg.substrg(pattern,1, size pattern-1), ) #"?" => s <> "" andalso match(strg.substrg(s,1,size s-1), Strg.substrg(pattern,1,size pattern-1)) c => s <> "" andalso Strg.sub(s,) = c andalso match(strg.substrg(s,1,size s-1), Strg.substrg(pattern,1,size pattern-1)) PK 28/9 moment 5 Sida 13 Uppdaterad 28-1-15 Funktionen matchstar (* matchstar(s,pattern,pos) Type: strg*strg*t->bool Pre: <=pos<=size s Post: sant om s - bortsett från pos (eller flera) tecken i början - matchar pattern, false annars. Ex: matchstar("abcd","cd",) = true matchstar("abcd","cd",3) = false *) (* Variant: size s - pos *) and matchstar(s,pattern,pos) = pos <= size s andalso (match(strg.substrg(s,pos,size s-pos), pattern) orelse matchstar(s,pattern,pos+1)) PK 28/9 moment 5 Sida 14 Uppdaterad 28-1-15 Testng av match... Exemplen tidigare ger typiska fall. Dessutom, för kodtäckng: match("","") = true match("a","") = false match("abc","*bc") = true match("","?bc") = false match("abc","?bc") = true match("","abc") = false match("xbc","abc") = false match("abc","abc") = true matchstar("abc","c",3) = false match("bc","c") = false matchstar("abc","c",1) = true matchstar("abc","c",2) = true Testng av match (forts.)... Dessutom, för gränsfall... match("","*") = true match("","?") = false match("","a") = false match("a","*") = true match("a","a*") = true match("a","*a") = true match("a","?") = true match("a","a?") = false match("a","?a") = false match("a","a") = true match("a","ab") = false match("a","ba") = false match("ab","*") = true match("ab","a*") = true match("ab","*b") = true match("ab","?") = false match("ab","a?") = true match("ab","?b") = true match("ab","?a") = false match("ab","a") = false match("ab","aa") = false match("ab","ab") = true PK 28/9 moment 5 Sida 15 Uppdaterad 28-1-15 PK 28/9 moment 5 Sida 16 Uppdaterad 28-1-15 Ömsesidig rekursion Använd rekursion för att visa om ett naturligt tal är udda eller jämnt. (* even n Type: t->bool Pre: n>= Post: true om n är jämnt, false annars. Ex: even 2 = true even 3 = false *) fun even = true even n = odd (n-1); (* odd n Type: t->bool Pre: n>= Post: true om n är udda, false annars. Ex: odd 2 = false odd 3 = true *) fun odd = false odd n = even (n-1); PK 28/9 moment 5 Sida 17 Uppdaterad 28-1-15 Ömsesidigt rekursion problem Programmet ovan fungerar te direkt i ML odd används (i even) nan den är defierad. Ömsesidigt rekursiva funktioner måste defieras tillsammans med hjälp av and-konstruktionen: - fun even = true even n = odd (n-1) and odd = false odd n = even (n-1); > val even = fn : t -> bool val odd = fn : t -> bool - even 5; > val it = false : bool - even 4; > val it = true : bool Vid ömsesidig rekursion måste ha varianten mska vid varje anrop även om det gäller olika funktioner med olika varianter. PK 28/9 moment 5 Sida 18 Uppdaterad 28-1-15

Kapslad rekursion välgrundade ordngar (* acker(n,m) Type: t*t->t Pre: n,m >= Post: Ackermanns funktion av n och m Ex: acker(2,2) = 7, acker(3,4) = 125 fun acker(,m) = m+1 acker(n,) = acker(n-1, 1) acker(n,m) = acker(n-1, acker(n,m-1)) Ackermanns funktion termerar, men det kan te visas med vår variantteknik. Det går te att förutse hur många anrop som behövs. Titta på båda argumenten samtidigt! Under den välgrundade ordngen (n1,m1) < (n2,m2) omm (om och ast om) n1<n2 eller n1=n2 och m1<m2 så mskar argumenten i varje anrop varje anrop är enklare så till slut måste man nå basfal. PK 28/9 moment 5 Sida 19 Uppdaterad 28-1-15 En gåta Termerar foo n för alla positiva heltal n? (* foo n Type: t->t Pre: n> (?!?!?!?) Post: 1 Ex: foo 4 = 1 foo 5 = 1 *) fun foo 1 = 1 foo n = if n mod 2 = then foo(n div 2) else foo(3*n+1) foo 4? 4, 2, 1 foo 5? 5, 16, 8, 4, 2, 1 foo 13? 13, 4, 2, 1, 5, 16, 8, 4, 2, 1 Här fns te ens någon välgrundad ordng (som man känner till)! PK 28/9 moment 5 Sida 2 Uppdaterad 28-1-15 Rekursion är te alltid direkt tillämplig Problem: Avgör om n är ett primtal! (* prime n Type: t->bool Pre: n> Post: true om n är ett primtal, false annars Ex: prime 4 = false prime 5 = true *) Problemuppdelng?? Kan man avgöra om n är ett primtal genom att veta om n-1 är ett primtal (enkel rekursion)? genom att veta att alla n <n är primtal (fullständig rekursion)? n är tydligen te rätt variabel att göra rekursion över, men vad är rätt i så fall? Generaliserg Ibland kan man te lösa ett problem direkt, utan man måste lösa ett mera allmänt problem först. Problem: avgör om n te är delbart med något tal från low till high. nodivisors(n,low,high) Type: t*t*t->bool Pre: n>, low>, low<=high+1 Post: true om n te är delbart med något tal från low till high, false annars. Ex: nodivisors(4,2,3) = false nodivisors(5,2,4) = true nodivisors kan skrivas med rekursion över t.ex. low. n är ett primtal omm (om och ast om) n te är delbart med något tal utom 1 och sig själv alltså från 2 till n-1. PK 28/9 moment 5 Sida 21 Uppdaterad 28-1-15 PK 28/9 moment 5 Sida 22 Uppdaterad 28-1-15 Programmet för primtalsbestämng (* nodivisors(n,low,high) Type: t*t*t->bool Pre: n>, low>, low<=high+1 Post: true om n te är delbart med något tal från low till high, false annars. Ex: nodivisors(4,2,3) = false nodivisors(5,2,4) = true *) (* Variant: high-low+1 *) fun nodivisors(n,low,high) = low > high orelse (n mod low) <> andalso nodivisors(n,low+1,high) (* prime n *) fun prime n = nodivisors(n,2,n-1) PK 28/9 moment 5 Sida 23 Uppdaterad 28-1-15 En konstruktionsmetodik Uppgift: Konstruera ett ML-program som beräknar en funktion f(a,...) givet en funktionsspecifikation (type, pre, post, ex) 1) Bestäm hur funktionen kan beräknas med hjälp av värdet för enklare data. Välj argumentet att göra rekursion över. Det kommer också att behövas fallanalys över detta. 2) Bestäm rekursionsvarianten och dokumentera den. 3) Ev. skriv defensiv kod för fall när rekursionsargumentet te uppfyller förvillkoret. 4) Skriv kod för basfal (fallen) utan att använda rekursion. 5) Skriv kod för det allmäna fal. Använd resultatet från rekursiva anrop (med enklare data) för att beräkna funktionsvärdet. Kontrollera för de rekursiva anropen att varianten mskar och att förvillkoret är uppfyllt! PK 28/9 moment 5 Sida 24 Uppdaterad 28-1-15

Introduktion till komplexitet Anta beräkngssteg för rekursiva program varierar med data. I prcip krävs flera steg när data är större, men hur många fler? Ex: sumupto n adderar heltal från till n. Anta steg är direkt proportionellt mot n blir n dubbelt så stor blir antal beräkngssteg dubbelt så stort. (Tids)komplexitet: O(n). Ljär tid. Ex: hanoi(n,from,via,to) som löser Hanoi-spe. För att beräkna hanoi för ett bestämt n, så måste hanoi anropas två gånger för n-1. En ökng av n med 1 ger alltså en fördubblg av anta beräkngssteg. (Tids)komplexitet O(2n). Exponentiell tid. Mneskomplexitet Även mnesåtgången varierar i allmänhet med data. Ex: iterativ sumupto n har en mnesåtgång som är konstant (oberoe av n). Mneskomplexitet O(1). Konstant mne. Ex: (icke svans-)rekursiv sumupto n har en mnesåtgång som är ljär (i n). Mneskomplexitet O(n). Ljärt mne. Mneskomplexiteten kan aldrig bli större än tidskomplexiteten? Varför? Skriv te program så att komplexiteten blir onödigt stor! Program med exponentiell tidskomplexitet är oftast praktiskt oanvändbara. PK 28/9 moment 5 Sida 25 Uppdaterad 28-1-15 PK 28/9 moment 5 Sida 26 Uppdaterad 28-1-15 Exponentierg Problem: Beräkna xn, där x är ett flyttal och n ett naturligt tal. (* expo(x,n) Type: real*t->real Pre: n>= Post: x upphöjd till n Ex: expo(2.,4) = 16. *) fun expo(x,) = 1. expo(x,n) = x*expo(x,n-1) Komplexiteten är ljär O(n). Val av algoritm påverkar komplexiteten x n = x n div 2 x n div 2 om n är jämn x n = x n div 2 x n div 2 x om n är udda. fun square x:real = x*x; fun fastexpo(x,) = 1. fastexpo(x,n) = square(fastexpo(x, n div 2)) * (if n mod 2 = then 1. else x) fastexpo har samma funktionsspecifikation (bortsett från funktionsnamnet) och rekursionsvariant som expo har. Vid varje rekursivt anrop blir n ungefär hälften så stor. Om anta anrop blir i, så var från början n! 2 i, alltså i! log 2 n Komplexiteten är logaritmisk O(log n). PK 28/9 moment 5 Sida 27 Uppdaterad 28-1-15 PK 28/9 moment 5 Sida 28 Uppdaterad 28-1-15 Lokala deklarationer Man kan låta deklarationer gälla ast uti ett uttryck. deklarationer... uttryck är självt ett uttryck där räckvidden för de angivna deklarationerna ast går till slutet av -uttrycket. val x = 3 val y = 2 x+y...beräknas till 5. Defitionerna av x och y är lokala i -uttrycket. PK 28/9 moment 5 Sida 29 Uppdaterad 28-1-15 En användng av lokala deklarationer fun fastexpo(x,) = 1. fastexpo(x,n) = square(fastexpo(x, n div 2)) * (if n mod 2 = then 1. else x) Hjälpfunktionen square kan ersättas av en lokal val-deklaration som sparar värdet av det rekursive anropet. fun fastexpo(x,) = 1. fastexpo(x,n) = val xn2 = fastexpo(x, n div 2) xn2 * xn2 * (if n mod 2 = then 1. else x) fastexpo(x, n div 2) räknas bara ut en gång fast dess värde används två gånger. PK 28/9 moment 5 Sida 3 Uppdaterad 28-1-15

Mns ni countchar2 (* countcharaux2(s,c,pos) Type: strg*char*t->t Pre: <=pos<=size s Post: Anta förekomster av c i s fr.o.m. position pos. Ex.: countcharaux2("hej, du glade",#"d",7)=1 countcharaux2("hej, du glade",#"d",3)=2 *) (* Variant: size s - pos *) fun countcharaux2(s,c,pos) = if pos >= size s then else if Strg.sub(s,pos)=c then countcharaux2(s,c,pos+1)+1 else countcharaux2(s,c,pos+1); (* countchar2(s,c) Type: strg*char->t Pre: (gen) Post: Anta förekomster av c i s Ex.: countchar2("hej, du glade",#"d")=2 countchar2("hej, du glade",#"q")= *) fun countchar2(s,c) = countcharaux2(s,c,); PK 28/9 moment 5 Sida 31 Uppdaterad 28-1-15 En annan användng av lokala deklarationer fun countchar2(s,c) = val ss = size s; (* countcharaux2(s,c,pos) *) fun countcharaux2(pos) = if pos >= ss then else if Strg.sub(s,pos)=c then countcharaux2(pos+1)+1 else countcharaux2(pos+1) countcharaux2() size s räknas bara ut en gång. countcharaux2 kan te användas utanför countchar2 s, c och ss behöver te ges som argument till countcharaux2 (de är fria i countcharaux2). PK 28/9 moment 5 Sida 32 Uppdaterad 28-1-15 Matchng i deklarationer I en val-deklaration är identifierarnamnet egentligen ett mönster! - val (x,y) = (1,2); > val x = 1 : t val y = 2 : t I detta fall måste uttrycket matcha mönstret, annars exekvergsfel! I en lokal deklaration kan matchng användas för att ta fram delarna av ett sammansatt funktionsvärde: fun qaddsimp(x,y) = val (p,q) = qadd(x,y); val gcdpq = gcd(p,q) (p div gcdpq,q div gcdpq) (qadd var en exempelfunktion som adderade rationella tal.) PK 28/9 moment 5 Sida 33 Uppdaterad 28-1-15 Funktionsdefitioner är syntaktiskt socker! Funktionsdefitioner är funktionsabstraktion+defitionsabstraktion. Detta kan man göra tydligt genom att göra funktionsabstraktionen med fn och defitionsabstraktionen med val! val rec addupto = fn => n => addupto(n-1)+n; Detta är precis detsamma som: fun addupto = addupto n = addupto(n-1)+n; nyckelordet rec tillåter att man använder det bundna namnet (addupto) i s egen defition "normalt är det te tillåtet eftersom namn måste bdas nan de används. (Även nyckelordet rec är syntaktiskt socker, men att visa hur man kan ersätta det med annan ML-kod är mycket komplicerat.) PK 28/9 moment 5 Sida 34 Uppdaterad 28-1-15 Lokala deklarationer är syntaktiskt socker! val v1 = uttryck1 val v2 = uttryck2 uttryck Är exakt samma sak som (fn v1 => (fn v2 => uttryck) uttryck2) uttryck1 PK 28/9 moment 5 Sida 35 Uppdaterad 28-1-15