Præsentation er lastning. Vent venligst

Præsentation er lastning. Vent venligst

GP 10, 7/11 20011 Grundlæggende programmering Efterår 2001 Forelæsning 10 onsdag 7/11 2001 kl. 9:15 – 12:00.

Lignende præsentationer


Præsentationer af emnet: "GP 10, 7/11 20011 Grundlæggende programmering Efterår 2001 Forelæsning 10 onsdag 7/11 2001 kl. 9:15 – 12:00."— Præsentationens transcript:

1 GP 10, 7/11 20011 Grundlæggende programmering Efterår 2001 Forelæsning 10 onsdag 7/11 2001 kl. 9:15 – 12:00

2 GP 10, 7/11 20012 Dagens program Det praktiske Rekursion

3 GP 10, 7/11 20013 Rekursion Dette er en anden måde at anskue løkker på. (kapitel 11). public boolean find(char ch, String str) { // returner sand hvis ch er i str if (str.length() == 0) return false; if (str.charAt(0) = ch) return true; return find(ch, str.substring(1, str.length() ) } Hvis str er tom, så fandt vi den ikke. Hvis det er det første bogstav, så fandt vi den. Ellers leder vi i resten af str. Rekursion angiver at en metode bruger sig selv under sin udførsel.

4 GP 10, 7/11 20014 Aktiveringsstak for find public boolean find(char ch, String str) { // returner sand hvis ch er i str if (str.length() == 0) return false; if (str.charAt(0) = ch) return true; return find(ch, str.substring(1, str.length() ) } ch: ’m’ str: ’Julemand’ ch: ’m’ str: ’ulemand’ ch: ’m’ str: ’lemand’ ch: ’m’ str: ’emand’ ch: ’m’ str: ’mand’

5 GP 10, 7/11 20015 Rekursion: Metoder der kalder sig selv En metode kan kalde en anden metode. En metode kan også kalde sig selv; dvs. dens metodekrop indeholder et kald til samme metodesignatur i kaldet som i hovedet. En metode, som indeholder et kald til sig selv, hedder (direkte) rekursiv og det pågældende kald er et rekursivt kald (eller rekursiv invokering). Det at referere til “sig selv” kaldes rekursion (fra Latin: recurrere, at køre igen). Udførslen af rekursive kald er som for alle kald: For hvert kald (lige meget om rekursiv eller ej) laves en ny metodeaktivering på kaldstakken, og hver gang et kald returnerer fjernes den øverste aktivering igen. Rekursiv design kræver rekursiv tænkning for at kunne udnytte udtrykskraften i rekursion og i at skrive programmer med rekursive metoder.

6 GP 10, 7/11 20016 Eksempel: Fakultetsfunktion Fakultetsfunktionen n! beregner produktet n * (n-1) *... * 2 * 1. Tallet angiver antal forskellige muligheder man har for at halsbånd med n forskellige perler. F.eks 20! = 24329020081766400. Man kan beregne fakultetsfunktionen iterativt vha. Man kan også beregne det rekursivt ved at indse, at n! = n * (n-1)! for n > 1, og n! = 1 for n = 1: static int factorial(int n) { int result = 1; while (n>1) result *= n; return result; } static int factorial(int n){ if (n>1) return n * factorial(n-1); else return 1;

7 GP 10, 7/11 20017 Eksempel: Towers of Hanoi Towers of Hanoi Problem: –Alle skiver skal flyttes fra tårn A til tårn B. –Kun en skive må flyttes ad gangen. –En større skive må aldrig ligge på en mindre skive. AB C

8 GP 10, 7/11 20018 Eksempel: Towers of Hanoi... Skriv et program, som genererer flytter skiverne. Hvordan gør vi? Grundide: Flyt de øverste n skiver fra tårn A til tårn B således: 1.Flyt de øverste n-1 skiver fra tårn A til tårn C. 2.Flyt den nederste skive fra tårn A til tårn B. 3.Flyt de n-1 øverste skiver fra tårn C til tårn B. F.eks., efter trin 1: AB C

9 GP 10, 7/11 20019 Eksempel: Towers of Hanoi... Fremgangsmåde: –Vi finder ud af, at vi har brug for en operation ”flyt N skiver fra tårn X til tårn Y med tårn Z som hjælpetårn”. –Vi skriver et metodehovede, samt tilhørende kommentar, hvad metoden skal gør: –Så skriver vi metodekroppen først for specielle argumentværdier: –Endelig skriver vi metodekroppen for alle andre værdier: // flyt(n, x, y, z) flytter de n øverste skiver fra tårn x til tårn y via tårn z public static void flyt(int antalSkiver, String fra, String til, String via) { if (n==1) // der er kun 1 skive at flytte; flyt den direkte til måltårnet System.out.println(”Flyt en skive fra ” + x + “ til “ + y); else { // udføres når der er mindst 2 skiver at flytte flyt(n-1, x, z, y); flyt(1, x, y, z); flyt(n-1, z, y, x); }}

10 GP 10, 7/11 200110 Eksempel: Towers of Hanoi... Læg mærke til at: –Vi bruger bare flyt i kroppen og lader som om det allerede er defineret. –Kommentaren på metodehovedet siger, hvad flyt gør når det kaldes. Det er vigtigt at: –du kan komme på en rekursiv formulering af problemet og problemløsningen (”tænke rekursivt”); –du husker at håndtere specielle værdier uden rekursivt kald, ellers går kroppen i en uendelig løkke.

11 GP 10, 7/11 200111 Kock fraktaler public void trekant(int order, int length){ fraktal(order,length); turn(120); fraktal(order,length); turn(120); fraktal(order,length); }

12 GP 10, 7/11 200112 Kock fraktaler Princippet er at man i stedet for at tegne en enkel linje, tegner en linje med et knæk på.

13 GP 10, 7/11 200113 Kock fraktaler public void fraktal(int order, int length){ if (order == 1) move(length); else { fraktal(order-1,length/3); turn(-60); fraktal(order-1,length/3); turn(120); fraktal(order-1,length/3); turn(-60); fraktal(order-1,length/3); }

14 GP 10, 7/11 200114 Forklaring public void fraktal(int order, int length){ if (order == 1) move(length); else { fraktal(order-1,length/3); turn(-60); fraktal(order-1,length/3); turn(120); fraktal(order-1,length/3); turn(-60); fraktal(order-1,length/3); } order angiver hvor mange knæk der skal være på en linje – på en eller anden måde. order = 1 angiver at der ikke skal laves knæk, men blot tegnes en linje. order >1 angiver at der skal laves knæk. Linjen knækkes ved at dele den op i 4 dele. Hver del tegnes en orden mindre.

15 GP 10, 7/11 200115 Aktiverings stak for fraktalen order: 3 length: 81 order: 2 length: 27 order: 1 length: 9

16 GP 10, 7/11 200116 Kaldsstakken i debuggeren Debuggeren er stoppet ved linjen ”move(length)” i metoden fraktal efter et kald med orden = 5. Man kan se at der er 5 aktiveringer af fraktal metoden i kaldsstakken på dette sted

17 GP 10, 7/11 200117 Sortering 2215443397237255347194511623927359138150 sorter hver halvdel for sig 2215443397237255347194511623927359138150 flet de to halvdele 2215443397237255347194511623927359138150

18 GP 10, 7/11 200118 Sorter en halvdel, kvarte,... 2215443397237255347 sorter hver kvart for sig 7237255347 2215443397237255347 flet de to kvarte 221544339 915223344 221544339 915223344 339 44339 44339 sorter hver kvart for sig flet de to kvarte sorter to tal flet

19 GP 10, 7/11 200119 Divide-and-conquer Grundideen bag mergesort (del-og-hersk, divide-and-conquer): For at sortere en tabel med n tal i, gør følgende: –del tabellen i to halvdele; –sorter begge halvdele hver for sig; –flet de to halvdele sammen som et lynlås. –(Se efterfølgende – mere om søgning og sortering næste gang).


Download ppt "GP 10, 7/11 20011 Grundlæggende programmering Efterår 2001 Forelæsning 10 onsdag 7/11 2001 kl. 9:15 – 12:00."

Lignende præsentationer


Annoncer fra Google