Föreläsning 5: Rekursion

Relevanta dokument
Rekursion: varför? Problem delas upp i mindre bitar algoritm för att lösa problemet erhålls från problemformuleringen

Vad är det och hur definierar vi en Biblioteksfunktioner (math) Top-down-programmering lokala globala variabler Arrays som in-parametrar

Individuellt Mjukvaruutvecklingsprojekt

Pesach Laksman är lärarutbildare i matematik och matematikdidaktik vid Malmö högskola.

4-3 Vinklar Namn: Inledning. Vad är en vinkel?

Föreläsning 4: Poster

Tankar om elevtankar. HÖJMA-projektet

Lathund, procent med bråk, åk 8

Föreläsning 6: Introduktion av listor

Skriva B gammalt nationellt prov

Algebra, polynom & andragradsekvationer en pampig rubrik på ett annars relativt obetydligt dokument

Modul 6: Integraler och tillämpningar

Tentamen i Programmering grundkurs och Programmering C

Presentationsövningar

Programmera en NXT Robot

Laborativ matematik som bedömningsform. Per Berggren och Maria Lindroth

Träning i bevisföring

När jag har arbetat klart med det här området ska jag:

( ostream ) << ( annan datatyp ) : ostream

VÄRDERINGSÖVNINGAR. Vad är Svenskt?

Boken om Teknik. Boken om Teknik är en grundbok i Teknik för åk 4 6.

Handledning för digitala verktyg Talsyntes och rättstavningsprogram. Vital, StavaRex och SpellRight

LÄSFÖRSTÅELSE PROVKAPITEL. Katarina Neiman Hedensjö

Kampanj kommer från det franska ordet campagne och innebär att man under en tidsbegränsad period bedriver en viss verksamhet.

Utveckla arbetsmiljö och verksamhet genom samverkan

Praktisk programmering

Vi skall skriva uppsats

Från min. klass INGER BJÖRNELOO

Kapitel 6. f(x) = sin x. Figur 6.1: Funktionen sin x. 1 Oinas-Kukkonen m.fl. Kurs 6 kapitel 1

Två konstiga klockor

Det är bra om även distriktsstyrelsen gör en presentation av sig själva på samma sätt som de andra.

NATIONELLA MATEMATIKTÄVLING

Koll på cashen - agera ekonomicoach!

Vanliga frågor. LEGOeducation.com. Konceptet. Processen

Tränarguide del 1. Mattelek.

Elektronen och laddning

Datorövning 2 Statistik med Excel (Office 2007, svenska)

Läraren som moderator vid problemlösning i matematik

Ett arbete som inte blev riktigt som Ann tänkt sig!

Idag: Dataabstraktion

Sammanfattning på lättläst svenska

729G04 - Hemuppgift, Diskret matematik

4 nödsamtal. SOS-operatören trycker nu på en knapp för att få fram telefonnummer och adress till telefonen pojken ringer från.

Och hur föreslår ni att man lyfter frågan om KA - ta upp det själv eller låta facket sköta snacket?

KUPOL en studie om skolmiljöns betydelse för ungdomars hälsa ENKÄT TILL ELEVER I ÅRSKURS 9

Jämförelse länder - Seminarium

Gruppenkät. Lycka till! Kommun: Stadsdel: (Gäller endast Göteborg)

4-6 Trianglar Namn:..

DOP-matematik Copyright Tord Persson. Bråktal Läs av vilka tal på tallinjen, som pilarna pekar på. Uppgift nr

7. SAMHÄLLSORIENTERING ÅK 5

Lisa besöker pappa i fängelset.

SANNOLIKHET. Sannolikhet är: Hur stor chans (eller risk) att något inträffar.

Hävarmen. Peter Kock

SOLCELLSBELYSNING. En praktisk guide. Råd & Tips SOLENERGI LADDA MED. Praktiska SÅ TAR DU BÄST HAND OM DIN SOLCELLSPRODUKT

Predikan Lyssna! 1 maj 2016

Gemensam problemlösning. Per Berggren och Maria Lindroth

Boll-lek om normer. Nyckelord: likabehandling, hbt, normer/stereotyper, skolmiljö. Innehåll

Hej! Mitt namn är Agota, och jag ringer från Smittskyddsinstitutet angående en telefonintervju om ditt deltagande i Sjukrapport. Pratar jag med XX?

Väga paket och jämföra priser

Du ska nu skapa ett litet program som skriver ut Hello World.

var väl Connysson som sade det, att det kändes som vi till och med,

Facit åk 6 Prima Formula

Lösningar s. 8 Perspek9v s. 7

DEMOKRATI 3 DEMOKRATINS VILLKOR

Svenska Du kan med flyt läsa texter som handlar om saker du känner till. Du använder metoder som fungerar. Du kan förstå vad du läser.

Bygg ditt eget dataspel på sommarlovet!

Kiwiböckerna metod och begrepp

BÅGSKYTTEFÖRBUNDET MEMBER OF SVERIGES RIKSIDROTTSFÖRBUND AND FÉDERATION INTERNATIONALE DE TIR A L ARC

Avsikt På ett lekfullt sätt färdighetsträna, utveckla elevers känsla för hur vårt talsystem är uppbyggt samt hitta mönster som uppkommer.

Efter att du har installerat ExyPlus Office med tillhörande kartpaket börjar du med att göra följande inställningar:

Hur du presenterar och marknadsför dig under själva intervjun är avgörande för att du ska bli en intressant kandidat.

Det flippade klassrummet hur uppfattas det av eleverna?

De två första korten Tidig position

FRÅN A TILL Ö LäraMera Ab / och Allemansdata Ab / FRÅN A TILL Ö

HT 2011 FK2004 Tenta Lärare delen 4 problem 6 poäng / problem

Mätningar på op-förstärkare. Del 3, växelspänningsförstärkning med balanserad ingång.

ÖSS jolles Seglarsaga

Sveriges Trafikskolors Riksförbund Film om körkort för nysvenskar Speakertext - Svensk

Snabbslumpade uppgifter från flera moment.

PROGRAMMERING A VB6 UTVECKLINGSVERKTYGET VISUAL BASIC

Anna Kinberg Batra Inledningsanförande 15 oktober 2015

Tunadalskyrkan i advent Ep 2 Petr 1: Profetorden en lampa i mörkret

TP #3. checklista - rättigheter och skyldigheter vid hyra. checklista: RÄTTIGHETER OCH SKYLDIGHETER VID HYRA HYRESAVTAL

Erfarenheter från ett pilotprojekt med barn i åldrarna 1 5 år och deras lärare

Sammanfatta era aktiviteter och effekten av dem i rutorna under punkt 1 på arbetsbladet.

Exempel på tentamensuppgifter i LMA100, del 1

Omvandla Vinklar. 1 Mattematiskt Tankesätt

INSTUDERINGSFRÅGOR TILL PROVET

Konsten att multiplicera (stora) heltal

På och avmastning. 1. Ensam är inte stark

Vid ett flertal tillfällen ställde individer frågor till Edgar Cayce om

Något om permutationer

P-02/03 säsongen 2016

Sammanfattning av kursdag 2, i Stra ngna s och Eskilstuna

Partnerskapsförord. giftorättsgods görs till enskild egendom 1, 2. Parter 3. Partnerskapsförordets innehåll: 4

Tentamen i matematisk statistik (9MA241/9MA341/LIMAB6, STN2) kl 08-13

Nämnarens adventskalendern 2007

Långt ifrån Zlatan VAD HANDLAR BOKEN OM? LGR 11 CENTRALT INNEHÅLL SOM TRÄNAS FÖRMÅGOR SOM TRÄNAS LGRS 11 CENTRALT INNEHÅLL SOM TRÄNAS

Programmeringsteknik med C och Matlab

912 Läsförståelse och matematik behöver man lära sig läsa matematik?

Transkript:

Föreläsning 5: Rekursion Vi har tidigare sett att man kan dela upp problem i mindre bitar med hjälp av underprogram, vilket är ett utmärkt sätt att lösa problem. Detta är ganska lätt att rita upp för sig själv. Tänk dig ett problem P som har "underproblemet" Q. För en programmerare innebär detta ett program P med ett underprogram Q. Ibland är det dock så att "underproblemet" är identiskt (eller nästan identiskt, det kanske skiljer någon parameter) med P. I detta fall är det inte ett annat program Q som skall anropas, utan P. Detta kanske låter lite knasigt nu i början, för vilket problem skulle kunna bara på detta sätt. Tja, t.ex. detta: Ett sätt att uttrycka det matematiska konceptet n-fakultet (N!) är att skriva det på följande vis: N!= 1 då N =0 N (N 1)! dån >0 Detta brukar kallas för den rekursiva definitionen, det finns även en annan definition som ser ut så här: N! = 1* 2 *... (N-1)*N då N > 0 0! = 1 Vi tänker oss nu att jag får i uppdrag av någon viktig person, t.ex. hans majestät kung Carl XVI Gustav, att skriva ett program som löser detta. Kungen kanske själv har kommit så långt så att han har ett huvudprogram, men tänker nu "outsource" resten av jobbet till mig. procedure Kungens_Program is K : Positive; K := Fakultet(3); Put(K); end Kungens_Program; Kungen ringer upp mig och befaller mig att koda detta underprogram Fakultet. Jag får resten av dagen på mig att göra detta. Som sann rojalist svarar jag artigt att detta skall jag göra. Har kommer få sitt program senast vid midnatt, och sedan lägger jag på luren. Jag sätter direkt igång med arbetet, kungen väntar ju! Jag vet vad programmet skall heta, och att det är en funktion (anropet står ju inte på egen rad). Vi kan börja med att fylla i detta. funktion Fakultet(... ) return... is Vi vet även att det som skall returneras alltid är ett positivt tal. Inparametern är - ja vadå? Vi kan ju skriva natural, men vad händer om man skulle skicka in ett negativt tal till fakultetsprogrammet? Här får vi gå tillbaka till definitionen - men det står ju inget! I detta fall är det alltså inte definierat vad som händer då man tar fakulteten av något negativt. Vi behöver alltså inte bry oss om detta fall! Om vi nu säger att inparametern har datatyp natural så vet vi i och för sig att programmet kommer att krascha när någon skickar in något negativt, men det får vi se som helt okej i detta läge.

funktion Fakultet(N : in Natural) return Positive is Nu kan vi börja fylla på med kod. Det finns ett lätt fall som vi kan ta hand om först, vi börjar med det. Här kan man fråga sig om man inte skall ha "else" istället för "end if", men om man funderar en stund så ser man att detta inte spelar någon roll. Om jag går in i denna if-sats kommer jag inte fortsätta nedåt i programmet i alla fall, eftersom det står return inuti if-satsen. Nu är frågan hur vi fortsätter. Hur räknar vi nu ut N-fakultet när N inte är 0? Vi vet att vi vill ta N gånger N-1-fakultet, men hur skriver vi detta egentligen? Vi kommer ungefär så här långt: funktion Fakultet(N : in Natural) return Positive is Om nu bara var N-1-fakultet så skulle ju detta lösa sig. Desvärre kommer det nog inte bli nånting om vi inte skriver något där. Nu börjar klockan närma sig 11 på kvällen och jag börjar få lite smått panik. Kungen vill ha sitt program om endast en timme, och jag har fortfarande inte löste problemet... Det bästa vore om det redan fanns ett program som löste N-1-fakultet, som jag kunde luta mig mot i detta läge. Alltså ungefär så här: funktion Fakultet(N : in Natural) return Positive is return N * Fakultet_2(N 1) ; Jag tänker mig här alltså att underprogrammet Fakultet_2 skulle lösa hela problematiken kring N-1- fakultet, så länge som det fungerar som det skall så fungerar ju mitt program. Då får jag plötsligt en strålande idé. Jag ringer upp min kompis Bengan som är en hejare på att koda. Jag förklarar noga situationen med Kungen, och att jag sitter lite i klistret här. Jag undrar om Bengan kanske skulle kunna skriva detta fakultet_2 program åt mig, jag har ju ändå gjort en del av jobbet redan. Trots att det bara är 45 minuter kvar lovar Bengan att lösa detta, och jag lägger på luren.

Bengan sätter igång med jobbet direkt. Han har fått veta av mig att programmet skall heta Fakultet_2, och att det skall vara en funktion. Han vet dessutom att returtypen måste vara ett positivt tal och att inparametern är en natural (eftersom mitt N inte var 0). Eftersom hans parameter bara existerar inuti Fakultet_2 kan han kalla sin parameter för N om han vill, även om han vet att den motsvarar min N-1. Han kommer så här långt: funktion Fakultet_2(N : in Natural) return Positive is end Fakultet_2; Hoppsan, tänker Bengan. "Vad gör jag nu. Jag lovade att göra ett N-1-fakultetsprogram, men får nu samma besvär som Erik hade". Tillslut kommer han fram till samma lösning som jag gjorde. Om det nu bara fanns ett program Fakultet_3 som räknade ut N-2-fakultet. Han kan ringa sin kompis! Men nu är det jäkligt brådis, bara 10 minuter till midnatt. Kompisen sätter igång direkt och kommer till, ja ni vet ju vad som händer: funktion Fakultet_3(N : in Natural) return Positive is end Fakultet_3; Men om man nu tittar noggrant på funktionerna Fakultet och Fakultet_2 så ser man något besynnerligt. De ser nästan exakt lika dana ut! Om man bara tar bort "_2" på den senare så får man ju tillbaka precis den funktion man hade från början. Om vi då leker med tanken att vi istället för att anropa Fakultet_2 anropar Fakultet, så blir ju resultatet faktiskt det samma. Dessutom kan vi ju göra detta hur många gånger som vi vill, mycket fler än vad vi har kompisar förmodligen. Som ni kanske förstår så gör man inte många kopior varje gång man skall göra en rekursiv funktion. Men man kan tänk sig att datorn gör det varje gång den rekursivt anropar sig själv. Man kan tänka sig det som en klon som får sina egna data. Varje klon kommer att göra sin beräkning och sedan returnera till sin föregångare. Vi kan nu gå igenom detta för vad som händer när man anropar funktionen fakultet med argumentet 3.

Här kommer nu lite tips på vad man bör tänka på när man skriver en rekursiv funktion: 1. En rekursiv funktion "hoppar alltid tillbaka" till den som anropade den (precis som alla underprogram). Man hoppar aldrig direkt tillbaka till huvudprogrammet. 2. Varje "klon" får sitt eget data. 3. När en "klon" anropar en annan "klon" så väntar den första tills den andra har kört klart. Övning på lektion Uppgift 1: Skriv en funktion som returnerar det N:te talet i Fibonacci-serien som definieras enligt: fib(1) = fib(2) = 1 fib(n) = fib(n - 1) + fib(n - 2) Gäller endast för positiva N. Lösning: function fib(n : in positive) return positive is if n <= 2 then y := 1; else y = fib(n 1) + fib(n 2); end fib; Styr så att det blir "exakt" på detta sätt. Varför? Jo, det kan vara så att de tycker att rekursion är svårt (!) När man sen returnerat sitt värde kan de vara bra att ta bort kopian av funktionen från tavlan. Att det kan vara extra "otrevligt" med just Fibonacci är att det är två anrop i samma uttryck. Detta gör att man måste poängtera att det kommer att ske samma sak igen för det andra uttrycket. Uppgift 2 : Skriv en funktion som beräknar x upphöjt till n. Här gäller det att studenterna skall komma fram till hur den rekursiva definitionen av funktionen ser ut. 1, n = 0 x^n = x * x^(n-1), n > 0 1 / x^(-n), n < 0 Denna är den kluriga!

Lösning: funktion Power(X, N : in float) return Float is x upphöjt till n (utan inbyggda operatorn). Vi tar inte hänsyn till "x = 0" fallet. if n = 0 then y := 1; elseif n > 0 then y := x * x_n(x, n 1); else y := 1 / x_n(x, n); end Power; OBS! I Ada finns en operator för "upphöjt till", ** för två heltal given, men vi skall givetvis inte använda denna. Det finns även ** för flyttal i Ada.Numerics.Elementary_Functions, inte heller något som behövs här alltså. Lösning: Uppgift 3: Skriv ett program som uppmanar användaren att mata in ett antal tal. Därefter skall talen matas in utan ledtext. Inmatningen avslutas då talet noll matas in. Funktionen skall dessutom skriva ut talen (men i omvänd ordning). procedure Main is procedure in_out is X : Integer; Get(X); if X /= 0 then in_out; Put(X); end in_out; Put("Mata in ett antal tal. Avsluta med 0"); in_out; end Main; Denna funktion utför saker både på vägen "in" och på vägen "ut". Trevligt. :-) Det man bör poängtera är att den rekursiva funktionen inte behöver vara själva huvudfunktionen. Detta kan t.ex. inträffa om rekursionen kräver fler parametrar än huvudfunktionen (kommer att vara så i sista uppgiften i laborationen).