Föreläsning 1-12 Innehåll Vektorer Registrering (räkna element av olika slag) Sökning Matriser Klasserna String och StringBuilder Repetition inför delmålskontroll 2 Undervisningsmoment: föreläsning 1-12 övning 4 laboration 7-8 Avsnitt i läroboken: 8.1-8.8, 8.1, 11 EDAA2 (F1-12 programmering) HT 216 1 / 59 Datastrukturer En datastruktur kan innehålla många element. har ett namn, men man kan även komma åt enskilda element. lista träd graf I kursen används listor i form av vektorer klassen ArrayList EDAA2 (F1-12 programmering) HT 216 2 / 59 Program med vektor Exempel public class MysteryProgram { public static void main(string[] args) { System.out.println("Skriv ett n-värde och " + "därefter n heltal:"); Scanner scan = new Scanner(System.in); int n = scan.nextint(); int[] v = new int[n]; for (int i = ; i < v.length; i++) { v[i] = scan.nextint(); for (int i = v.length - 1; i >= ; i--) { System.out.println(v[i]); Vad gör programmet? EDAA2 (F1-12 programmering) HT 216 3 / 59 Deklarera vektorer Vektorer deklareras precis som andra variabler med datatyp namn elementens typ int[] v; Markerar att det är en vektor och inte en vanlig int-variabel vektorns namn Vektorer är objekt i Java. v är alltså en referensvariabel. Observera att själva vektorn inte är skapad ännu. EDAA2 (F1-12 programmering) HT 216 4 / 59 v
Skapa vektorer Vektorer är objekt vektorns namn elementens typ v = new int[5]; Antal element måste anges. Elementen får automatiskt startvärden. antal element v [] [1] [2] [3] [4] Oftast deklarerar och skapar man vektorn på samma gång: int[] v = new int[5]; v [] [1] [2] [3] [4] 42 3 13 5 7 Vektorer är objekt i Java. v refererar till vektorn (vilket framgår av bilden ovan). Men ofta ritar man en enklare bild av vektorn: 1 2 3 4 v 42 3 13 5 7 EDAA2 (F1-12 programmering) HT 216 5 / 59 EDAA2 (F1-12 programmering) HT 216 6 / 59 Använda vektorelement Ta reda på vektorns längd vektorns namn index Använd length för att ta reda antal element i vektorn. v[] = 42; Ett vektorelement används som en vanlig variabel. Det är viktigt att indexet håller sig inom gränserna [, antal element 1] for (int i = ; i < v.length; i++) { v[i] = scan.nextint(); Tänk på att elementen numreras från och uppåt. EDAA2 (F1-12 programmering) HT 216 7 / 59 EDAA2 (F1-12 programmering) HT 216 8 / 59
Övning Skapa vektor Deklarera och skapa en vektor numbers med plats för 5 stycken element av typen double. Tilldela första elementet värdet 7.2. numbers [] [1] [2] [3] [4] 7.2 1. 1. 1. 1. Deklarera och skapa en vektor exist med plats för 4 stycken element av typen boolean. Tilldela tredje elementet värdet true. exist [] [1] [2] [3] false false true false Vektorer är objekt Referenstilldelning Vad händer i detta exempel? Hur många vektorer skapas? Vad refererar b till? Komplettera bilden. int[] a = new int[3]; a[] = 7; a[1] = 8; a[2] = 9; int[] b = a; a [] 7 [1] 8 [2] 9 EDAA2 (F1-12 programmering) HT 216 9 / 59 EDAA2 (F1-12 programmering) HT 216 1 / 59 Kopiera vektorer Exempel Kopiera a, dvs. skapa en ny vektor med samma innehåll som a. int[] a = new int[3]; a[] = 7; a[1] = 8; a[2] = 9; int[] b = new int[a.length]; for (int i = ; i < a.length; i++) { b[i] = a[i]; Genvägar Överkurs, men praktiskt // Skapa en vektor när man vet innehållet: int[] a = {7, 8, 9; // Kopiera en vektor till en ny vektor med längden a.length: int[] b = Arrays.copyOf(a, a.length); // Metoden Arrays.toString returnerar en sträng med vektorns // innehåll. Skriv ut innehållet i vektorn: System.out.println(Arrays.toString(b)); a [] 7 [1] 8 [2] 9 b [] 7 [1] 8 [2] 9 a [] 7 [1] 8 [2] 9 b [] 7 [1] 8 [2] 9 EDAA2 (F1-12 programmering) HT 216 11 / 59 EDAA2 (F1-12 programmering) HT 216 12 / 59
Lagra objekt i vektorer Lagra objekt i vektorer forts Vektorn vertices med plats för tre Point-objekt: Point[] vertices = new Point[3]; vertices[] = new Point(1,15); vertices[1] = new Point(5,1); vertices[2] = new Point(9,12); vertices [] [1] [2] null null null vertices Varje vektorelement är en referensvariabel av typen Point. Observera att vi inte har skapat några punktobjekt ännu, bara en vektor med plats för punkter. x y 1 15 x y 5 1 x y 9 12 EDAA2 (F1-12 programmering) HT 216 13 / 59 EDAA2 (F1-12 programmering) HT 216 14 / 59 Klassen Triangle Huvudprogram som använder klassen Triangle public class Triangle { private Point[] vertices; // triangelns hörnpunkter /** Skapar en triangel med hörnpunkterna x1,y1 x2,y2 x3,y3. */ public Triangle(int x1,int y1,int x2,int y2,int x3,int y3) { vertices = new Point[3]; vertices[] = new Point(x1,y1); vertices[1] = new Point(x2,y2); vertices[2] = new Point(x3,y3); /** Ritar triangeln i fönstret w. */ public void draw(simplewindow w) { w.moveto(vertices[].getx(), vertices[].gety()); for (int i = 1; i < vertices.length; i++) { w.lineto(vertices[i].getx(), vertices[i].gety()); w.lineto(vertices[].getx(), vertices[].gety()); EDAA2 (F1-12 programmering) HT 216 15 / 59 public class TriangleExample { public static void main(string[] args) { Triangle t = new Triangle(1, 15, 5, 1, 9, 12); SimpleWindow w = new SimpleWindow(2, 2, "Triangel"); t.draw(w); EDAA2 (F1-12 programmering) HT 216 16 / 59
Registrering Exempel på användning av heltalsvektor Uppgift: Räkna antal element av olika slag. Lösning: Använd en vektor av typ int[] för att lagra de olika antalen. Räkna mynt.vi behöver en låda för enkronor, en för femkronor och en för tiokronor: int[] nbrcoins = new int[3]; enkronor femkronor tiokronor EDAA2 (F1-12 programmering) HT 216 17 / 59 räkna antal 6:or public class DieTest { public static void main(string[] args) { Die d = new Die(); Scanner scan = new Scanner(System.in); System.out.println("Antal tärningskast: "); int nbrrolls = scan.nextint(); int nbr6 = ; for (int i = ; i < nbrrolls; i++) { d.roll(); if (d.getresult() == 6) { nbr6++; System.out.println("Det blev en 6:a i " + (double) nbr6/nbrrolls * 1 + " % av fallen"); Ändra i programmet så att även antal 1:or, antal 2:or,... räknas. EDAA2 (F1-12 programmering) HT 216 18 / 59 räkna antal olika tärningskast registrera poäng Räkna antal 1:or, antal 2:or... int[]res = new int[6]; for (int i = ; i < nbrrolls; i++) { d.roll(); res[d.getresult() - 1]++; res 16454 1 16512 2 16786 3 16725 4 16731 5 16792 antal 1:or antal 2:or antal 6:or Antag att ett antal studenter har skrivit ett prov. På provet kan man ha max 5 poäng. Vi ska räkna antal studenter som har, 1,..., 5 poäng. antal studenter som har -9, 1-19, 2-29, 3-39, 4-5 poäng. Vi koncentrerar oss här bara på registreringen och och skriver ett litet huvudprogram där vi antar att antal studenter är 1. Poängen slumpar vi fram. (De blir rektangelfördelade vilket är orealistiskt.) I läroboken finns det ett större exempel med klasser för studenter och prov. EDAA2 (F1-12 programmering) HT 216 19 / 59 EDAA2 (F1-12 programmering) HT 216 2 / 59
registrera poäng, 1,..., 5 public class RegExample { public static void main(string[] args) { Random rand = new Random(); int[] nbrs = new int[5]; // antal med poäng, // antal med 1 poäng... for (int i = ; i < 1; i++) { int p = rand.nextint(51); // slumpa poäng nbrs[p]++; // notera poängen System.out.println(Arrays.toString(nbrs)); nbrs antal med poäng 1 antal med 1 poäng 2 antal med 2 poäng... 5 antal med 5 poäng registrera poäng -9, 1-19, 2-29, 3-39, 4-5 Vi har 5 intervall och behöver en vektor med 5 platser: int[] nbrs = new int[5]; Översättning från poängantal till index: int index = p / 1; Poängantalet 5 måste särbehandlas. nbrs -9 poäng 1-19 poäng 1 2 2-29 poäng 3 3-39 poäng 4 4-5 poäng EDAA2 (F1-12 programmering) HT 216 21 / 59 EDAA2 (F1-12 programmering) HT 216 22 / 59 registrera poäng -9, 1-19, 2-29, 3-39, 4-5, forts Registrering Kommentar public class RegExampleInterval { public static void main(string[] args) { Random rand = new Random(); int[] nbrs = new int[4]; // antal med -1 poäng, // antal med 1-19 poäng... for (int i = ; i < 1; i++) { int p = rand.nextint(51); // slumpa poäng int index = p / 1; // Ex: 37 poäng ger index 3 if(index == 5){ //särbehandla 5 poäng index = 4; nbrs[index]++; System.out.println(Arrays.toString(nbrs)); Passar det alltid att använda en heltalsvektor för att räkna antal av olika slags element? Ideexempelvianvänthardetvaritlättattöversättafrån slagav element till index i resultatsvektorn. I andra fall är det svårare. Antag att vi ska räkna antal förekomster av olika ord i en text. I så fall är det bättre att vi lagrar ordet tillsammans med antal förekomster i någon annan datastruktur. Det finns färdiga klasser i Java som kan användas i sådana fall (t.ex. HashMap) Detta behandlas i en senare kurs. EDAA2 (F1-12 programmering) HT 216 23 / 59 EDAA2 (F1-12 programmering) HT 216 24 / 59
Linjärsökning Mönster Uppgift: Sök upp givet element i en följd av element. Lösning: Gå igenom elementen i tur och ordning och kontrollera för varje element om det är det sökta. Avbryt om det sökta elementet påträffas. EDAA2 (F1-12 programmering) HT 216 25 / 59 Diskutera public static int indexof(int[] v, int nbr) { for (int i = ; i < v.length; i++) { if (v[i] == nbr) { return i; else { return -1; Varför fungerar inte det här? EDAA2 (F1-12 programmering) HT 216 27 / 59 Linjärsökning Med for-sats Algoritm: for (int i = ; i < "antal element"; i++) { if ("elementet på plats i är det vi söker") { avbryt /** Sök efter talet nbr i vektorn v. Om nbr finns returneras platsen för nbr, annars -1 */ public static int indexof(int[] v, int nbr) { for (int i = ; i < v.length; i++) { if (v[i] == nbr) { return i; return -1; EDAA2 (F1-12 programmering) HT 216 26 / 59 Linjärsökning Med while-sats Algoritm: i = "platsen för det första elementet" while ("fler element kvar att söka igenom" && "elementet på plats i inte är det vi söker") i = platsen för nästa element public static int indexof(int[] v, int nbr) { int i = ; while (i < v.length && v[i]!= nbr) { i++; if (i < v.length) { return i; else { return -1; EDAA2 (F1-12 programmering) HT 216 28 / 59
Diskutera Ordningen mellan delvillkoren är viktig. Varför måste jämförelsen i < v.length göras först? int i = ; while (i < v.length && v[i]!= nbr) { i++; Varför kan man inte använda villkoret v[i] == nbr för att avgöra om man funnit talet nbr eller ej? if (i < v.length) { return i else { return -1; Linjärsökning Kommentar I exemplet på föregående sida förutsäter vi att vektorns alla platser används och ska sökas igenom. Vi har alltså v.length element att söka igenom: while (i < v.length && v[i]!= nbr) I motsvarande exempel i läroboken (avsnitt 8.8) har man en vektor där de bara de n första platserna i vektorn utnyttjas: while (i < n && v[i]!= nbr) { EDAA2 (F1-12 programmering) HT 216 29 / 59 EDAA2 (F1-12 programmering) HT 216 3 / 59 Klassen Arrays I Java finns det en klass Arrays som innehåller en hel del metoder bland annat för att söka i vektorer och sortera. Antag att vi har en vektor v av typen int[] med sorterade heltal. Då kan vi söka efter platsen för talet 42 på följande sätt: int index = Arrays.binarySearch(v, 42); Vektorn kan sorteras genom följande anrop: Arrays.sort(v); Att använda denna klass ingår ej i kursen, men det kan vara bra att veta att det finns en hel del färdigt om du fortsätter skriva program efter kursens slut. Vill du veta mera så se vidare i Javas dokumentation. EDAA2 (F1-12 programmering) HT 216 31 / 59 polygon Vektorer med godtyckligt antal element Antag att vi vill hantera polygoner med ett godtyckligt antal hörnpunkter. Vi måste skapa en tillräckligt stor vektor för punkterna. Det behövs också en variabel som håller reda på hur många punkter vi satt in i vektorn: Point[] vertices = new Point[8]; int n = ; 1 2 3 4 vertices null null null null null n 5 6 7 null null null EDAA2 (F1-12 programmering) HT 216 32 / 59
polygon forts Polygon med fyra hörnpunkter vertices 1 2 3 4 null 5 6 7 null null null Sätta in en ny punkt Insättning av en ny punkt efter de andra punkterna i polygonen: vertices[n] = new Point(2, 4); n++; vertices 1 2 3 4 5 6 7 null null null x 5 x 7 x 35 x 32 y 5 y 3 y 35 y 2 x 5 x 7 x 35 x 32 x 2 y 5 y 3 y 35 y 2 y 4 n 4 n 5 EDAA2 (F1-12 programmering) HT 216 33 / 59 EDAA2 (F1-12 programmering) HT 216 34 / 59 Klassen Polygon Ta bort en punkt public class Polygon { private Point[] vertices; private int n; // polygonens hörnpunkter // antal hörnpunkter Borttagning av punkten på plats pos i vektorn vertices: Täpp till hålet i vektorn genom att flytta flytta alla element efter pos ett steg till vänster. Uppdatera n eftersom antal punkter minskat med 1. /** Skapar en polygon med max 8 hörnpunkter. */ public Polygon() { vertices = new Point[8]; n = ; /** Sätter in en ny punkt med koordinaterna x, y. */ public void addvertex(int x, int y) { vertices[n] = new Point(x, y); n++; public void removevertex(int pos) { for (int i = pos; i < n - 1; i++) { vertices[pos] = vertices[pos + 1]; vertices[n - 1] = null; n--; EDAA2 (F1-12 programmering) HT 216 35 / 59 EDAA2 (F1-12 programmering) HT 216 36 / 59
Före borttagning av punkten Efter borttagning av punkten vertices 1 2 3 4 5 6 7 null null null vertices 1 2 3 4 null 5 6 7 null null null x 5 x 7 x 35 x 32 x 2 y 5 y 3 y 35 y 2 y 4 x 5 x 35 x 32 x 2 y 5 y 35 y 2 y 4 n pos 5 1 n pos 4 1 EDAA2 (F1-12 programmering) HT 216 37 / 59 EDAA2 (F1-12 programmering) HT 216 38 / 59 Passar en vektor för detta? Linjärsökning Klassen Polygon I exemplet på föregående bilder måste vi gissa hur stor vektor vi behöver. Vad händer om vi vill sätta in fler än 8 punkter? Då måste vi skapa en ny större vektor. För problem där antal element varierar är det enklare att använda den färdiga klassen ArrayList (behandlas senare i kursen). Ett ArrayList-objekt använder internt en vektor och har färdiga metoder för att sätta in element i listan, ta bort element etc. Lägg till en metod som undersöker om punkten x, y ingår bland polygonens hörnpunkter. public boolean hasvertex(int x, int y) { for (int i = ; i < n; i++) { if (vertices[i].getx() == x && vertices[i].gety() == y) { return true; return false; EDAA2 (F1-12 programmering) HT 216 39 / 59 EDAA2 (F1-12 programmering) HT 216 4 / 59
Håll koll på typerna Matriser Kontrollera att typerna stämmer vid tilldelningar och jämförelser för att undvika fel. namn typ index i int vektorn med punkter vertices Point[] en punkt vertices[i] Point punktens x-koordinat vertices[i].getx() int punktens y-koordinat vertices[i].gety() int rad rad 1 rad 2 kolonn 7 22 11 kolonn 1 9-18 16 kolonn 2 123 12-4 kolonn 3 41 3 kolonn 4 1-2 1 EDAA2 (F1-12 programmering) HT 216 42 / 59 EDAA2 (F1-12 programmering) HT 216 41 / 59 Deklarera och skapa matriser Använda matriser Att använda ett matriselement: elementens typ radindex kolonnindex int[][] m = new int [3][5]; m[2][] = ; antal rader antal kolonner Man kan ta reda på antal rader: m.length och antal kolonner på raden i: m[i].length EDAA2 (F1-12 programmering) HT 216 43 / 59 EDAA2 (F1-12 programmering) HT 216 44 / 59
Övning Matris Exempel Matris Deklarera och skapa en matris som representerar ett schackbräde med 8 x 8 rutor. På rutorna ska man kunna placera schackpjäser som beskrivs av en klass ChessPiece. Beräkna och skriv ut radsummorna i en 3 x 5-matris. för varje rad för varje element på raden behandla elementet for (int i = ; i < m.length ; i++) { int sum = ; for (int k = ; k < m[i].length; k++) { sum = sum + m[i][k]; System.out.println(sum); EDAA2 (F1-12 programmering) HT 216 45 / 59 EDAA2 (F1-12 programmering) HT 216 46 / 59 Övning Matris Antag att vi har en matris booked av typen boolean[][] som ska användas för att hålla reda på bokade platser i en biosalong. Varje matriselement motsvarar en plats i salongen och har värdet true om platsen är bokad, i annat fall värdet false. Skriv satser som räknar antal bokade platser. Klassen String Klassen String beskriver en teckensträng (en följd av tecken). Tecknen kan läsas av men inte ändras. String s = "En massa tecken"; String empty = ""; s empty En massa tecken EDAA2 (F1-12 programmering) HT 216 47 / 59 EDAA2 (F1-12 programmering) HT 216 48 / 59
Slå ihop (konkatenera) strängar Behandla alla tecken i strängen String s1 = "En text"; String s2 = "En text till"; String result = s1 + " och " + s2; Mönster: String s =...; for (int i = ; i < s.length(); i++) { // aktuellt tecken nås med anropet s.charat(i); s1 s2 result En text En text till En text och En text till Räkna antal blanktecken i strängen s. int spaces = ; for (int i = ; i < s.length(); i++) { if (s.charat(i) == ) { spaces++; EDAA2 (F1-12 programmering) HT 216 49 / 59 EDAA2 (F1-12 programmering) HT 216 5 / 59 Övning Jämföra teckensträngar med equals Vad skrivs ut? Förklara varför. Scanner scan = new Scanner(System.in); String s1 = scan.next(); String s2 = scan.next(); if (s1 == s2) { System.out.println("Lika"); else { System.out.println("Inte lika"); s1 s2 abc abc Vill man jämföra innehållet i teckensträngarna måste man använda metoden equals: /** Returnerar true om innehållet i aktuell sträng är lika med innehållet i s. */ boolean equals(object s); if (s1.equals(s2)) { System.out.println("Samma innehåll"); else { System.out.println("Inte samma innehåll"); EDAA2 (F1-12 programmering) HT 216 51 / 59 EDAA2 (F1-12 programmering) HT 216 52 / 59
Jämföra teckensträngar med compareto Klassen StringBuilder Med metoden compareto kan man avgöra om en sträng är större än eller mindre än en annan sträng: /** Jämför aktuell sträng med s. Returnerar om teckensträngarna är lika, ett negativt tal om aktuell sträng är mindre än s, ett positivt tal om aktuell sträng är större än s. */ int compareto(string s); Klassen StringBuilder beskriver en följd av tecken som kan läsas och ändras. StringBuilder b = new StringBuilder("En massa tecken"); b.append("!"); String s1 = "java"; s1.compareto("java") == s1.compareto("javac") < s1.compareto("java") > s1.compareto("jazz") < b En massa tecken! EDAA2 (F1-12 programmering) HT 216 53 / 59 EDAA2 (F1-12 programmering) HT 216 54 / 59 Några metoder i klassen StringBuilder /** Skapar en tom strängbuffert. */ StringBuilder(); /** Skapar en strängbuffert med samma innehåll som s. */ StringBuilder(String s); /** Tar reda på antal tecken. */ int length(); /** Tar reda på tecknet på plats pos. */ char charat(int pos); /** Returnerar ett String-objekt med samma innehåll som denna strängbuffert. */ String tostring(); Ändra innehållet i StringBuilder-objekt /** Lägger in s efter tecknen i strängbufferten. */ StringBuilder append(string s); /** Ändrar tecknet på plats k till ch. */ void setcharat(int k, char ch); /** Lägger in s på plats k, flyttar tecknen efter. */ StringBuilder insert(int k, String s); /** Tar bort tecknet på plats k. */ StringBuilder deletecharat(int k); Man kan sätta in värden av andra typer än String i ett StringBuilderobjekt. Det finns flera metoder append och insert. Dessa har en parameter av typen int, double, char,... EDAA2 (F1-12 programmering) HT 216 55 / 59 EDAA2 (F1-12 programmering) HT 216 56 / 59
Metoden tostring Det är vanligt att man lägger till metoden tostring i sina klasser. Metoden tostring anropas t.ex. inuti println och används av debuggern när ett objekt ska skrivas ut. Metoden tostring i klassen Point (kap. 3) kan se ut så här: public String tostring() { return x + " " + y; eller så här: Delmål 2 Repetition På föreläsning 12 blir det repetition inför delmålskontroll 2. Det vi ska repetera är framförallt: implementering av klasser använda vektorer och matriser Material till denna repetitionsföreläsning delas ut separat. public String tostring() { StringBuilder b = new StringBuilder(); b.append(x); b.append( ); b.append(y); return b.tostring(); EDAA2 (F1-12 programmering) HT 216 57 / 59 EDAA2 (F1-12 programmering) HT 216 58 / 59 Checklista Exempel på vad du ska kunna Förklara begreppen datastruktur, vektor, matris. Deklarera, skapa och använda vektorer och matriser. Formulera algoritmer och programkod för att söka i en vektor eller matris (linjärsökning). Formulera algoritmer och programkod för att räkna antal element av olika slag (registrering). Använda klasserna String och StringBuilder Implementera och använda klasser (större än tidigare). EDAA2 (F1-12 programmering) HT 216 59 / 59