Nada

^ Upp till kursens hemsida.

fovgrund02, Datalogi I, gk med Javaprogrammering för PVT

Program som jag planerar att gå igenom på lektionerna tredje kursveckan (vecka 43) och som inte finns i läroboken.

Demonstration av ModelViewController - mönstret

En applet med en lampa som kan tändas och släckas och vars storlek kan ökas och minskas. Modellen, klassen LampModel innehåller allt som har med lampan att göra, bl.a. dess position och radie samt metoder för att tända, släcka och rita lampan. Klassen View är en Canvas där lampan ritas upp. Klassen Controller är en Panel där alla kontrollknappar ligger och den är samtidigt lyssnare efter de ActionEvent som genereras då användaren trycker på knapparna. Till sist, klassen LampDemo är en Applet som skapar ett objekt vardera av klasserna LampModel, View och Controller. Objekten av View och Controller är båda subklasser till grafiska komponenter. View är en Canvas och Controller är en Panel. De båda läggs i appleten (som själv är en Panel) med metoden add.

En viktig sak med detta exempel är vilka klasser som känner till varandra:

Observera att alla förändringar av lampans tillstånd görs i modell-objektet, viewobjektet visar bara upp en bild av hur modellen ser ut. Fördelen med detta är bl.a. att View-klassen lätt kan bytas ut om man vill presentera modellen på ett annat sätt. Exemplet visar också på användning av de grafiska komponenterna Canvas och Panel samt en GridLayout. Controller - objektet som är en Panel använder GridLayout för att få alla knapparna säkert på rad och lika stora.
Kör appleten

Brinnande stearinljus

Ett enkelt exempel på användning av trådar för animering. Klassen Candle beskriver ett stearinljus som börjar brinna så snart man man skapat ljuset. Varje ljus har (är) en egen tråd och brinnförloppet pågår oberoende av andra aktiviteter i programmet. I appleten kan man skapa fler ljus (max 7 st) genom att trycka på en knapp. Skapar man fler än 7 st lagras de på plats 0, 1, 2 o.s.v. Ljusen lagras in en vektor, en Candle[]. Detta för att programmet ska gå att köra i Browsers som bara har Java 1.1. Det vore annars smidigare att använda en ArrayList för att spara godtyckligt många ljus.

Javakoden för Candle.java
Javakoden för appleten
Kör appleten

Bilden ovan flimrar ganska mycket. Den ritas med en paint-metod i appleten på samma sätt som alla stillbilder vi ritat tidigare i kursen, fast bilden ritas om med 0.4 sekunders mellanrum. Flimret beror på att den gamla bilden suddas innan nästa bild ritas. Flimret kan minskas t.ex. genom att man ritar i en extra bildbuffert som man visar i appletfönstret först när den är färdigritad. Så har jag gjort i exemplet nedan:
Javakoden för appleten
Kör appleten

Sierpinskitriangel

Detta vackra mönster är ett exempel på en bild med en rekursiv definition som är relativt lätt att rita med en rekursiv metod men vore besvärligt utan hjälp av rekursion.
Javakoden för appleten
Kör appleten

Snöflingekurva

Här är ett annat exempel på ett rekursivt mönster. En linje delas upp i 4 linjesegment genom att man först delar linjen i 3 lika långa bitar, den mittersta ersätts med 2 linjestycken enligt följande princip: Låt det mittersta linjestycket vara bas in liksidig triangel, ersätt linjestycket med de två andra triangelsidorna. Om detta görs för alla tre sidorna i en liksidig triangel så fås en regelbunden 6-uddig stjärna. Om förfarandet upprepas rekursivt så fås en så kallad snöflingekurva. Matematiken i detta exempel, att beräkna koordinaterna för den nya punkt som inte ligger på den ursprungliga linjen, är lite svårare än för Siepinskitriangeln.
Javakoden för appleten
Kör appleten

Rekursiv metod för strängvändning

En rekursiv algoritm är en som refererar till sig själv. Grundprincipen för de enklaste rekursiva algoritmerna är följande: Antag att vi har ett problem att lösa som har en viss storlek n, problemet kallar vi P(n). Antag att vi kan lösa problemet för storleken n-1, P(n-1) (eller att vi kan lösa problemet för något annan, mindre storlek). Antag också att problemet har en enkel lösning som vi direkt kan få tag på för något liten storlek, t.ex. 0 eller 1, alltså Att vända bakochfram på en text kan formuleras rekursivt. Vi kallar problemet för vänd. Antag att s1 är första tecknet i strängen s och att rest(s) är strängen s utom första tecknet. Om s = "BIO" så är s1= "B" och rest(s) = "IO" I steget vänd(rest(s)) utnyttjar vi antagandet att vi kan lösa problemet för en storlek mindre än den vi startar med eftersom rest(s) har ett tecken mindre än vad s har. Att vända på en sträng med längden 1 är inget jobb alls, vänd(s) = s om s har längden 1. Exempel:

vänd("SUNGAM") = vänd("UNGAM") + "S" =
vänd("NGAM") + "U" + "S" =
vänd("GAM") + "N" + "U" + "S" =
vänd("AM") + "G" + "N" + "U" + "S" =
vänd("M") + "A" + "N" + "U" + "S" =
"M" + "A" + "N" + "U" + "S" = "MAGNUS"

Detta kan man göra i Java. Man får använda metoderna s.length() som ger antalet tecken i strängen s, samt s.substring(k) som ger delsträngen av s som startar i position k, samt s.substring(k,l) som ger delsträngen som startar i position k och har längden l.
Här finns metoden i Java samt ett exempel på anrop av metoden.

Om du inte gått på lektionerna och tycker att rekursion är svårt att förstå, försök att låna någon Java-lärobok där rekursion tas upp och/eller läs Datalogiboken (Lunell), avsnitt 4.4 om programspråksimplementation.