Orga Universität Paderborn Prof. Dr. Heike Wehrheim Prüfungsanmeldung für diejenigen, die einen Leisungsnachweis (insbesondere für Lehramt mit Erweiterungsfach Informatik) benötigen sowie für Austauschstudenten Formular dafür von unserer Webseite runterladen, ausfüllen, im Briefkasten vor E4.321 einwerfen Zwischenklausur ist am Dienstag, 2. Dezember 2008 im Audimax Abmeldung (für Prüfung GP1 insgesamt) bis 25. November 2008 GPI, WS 07/08 191 Fragen II Universität Paderborn Prof. Dr. Heike Wehrheim Wieviele Iterationen ergibt a) for (int i = 1; i < 100; i++) ? b) for (int i = 99; i >=0; i--) ? c) i=0; while (i < 11) { i=i+2; } ? GPI, WS 07/08 192 Universität Paderborn Prof. Dr. Heike Wehrheim Kapitel 1: Grundlegende Programmierkonstrukte 1.4 Arrays - Felder GPI, WS 07/08 193 Motivation Universität Paderborn Prof. Dr. Heike Wehrheim Beispiel: Sie wollen die Klausurergebnisse von 100 Studenten speichern, und dann bearbeiten (z.B. ausrechnen, wieviele bestanden haben) bisher: dafür 100 int (oder double) Variablen deklarieren ergebnis1, ergebnis2, ergebnis3, … aber … wie greift man auf das i-te Ergebnis zu (z.B. in einer ForSchleife mit Zähler i)? … und was ist, wenn man 1000 Studenten hat? Für eine solche Folge von gleichartigen Elementen (hier Klausurergebnisse) wird in Programmiersprachen das Konzept des Arrays benutzt GPI, WS 07/08 194 Arrays - Felder Universität Paderborn Prof. Dr. Heike Wehrheim Arrays repräsentieren Folgen gleichartiger Elemente (d.h. gleichen Typs) mit Zugriff durch Indizierung. Im vorherigen Beispiel: Wir können eine Array-Variable noten deklarieren, die alle 100 Ergebnisse aufnehmen kann Auf das 45-te Ergebnis kann direkt zugegriffen werden: noten[44] die Zahl 44 ist hierbei der Index als Index kann nicht nur ein Literal, sondern auch eine Variable benutzt werden noten[i] dann wird das Element entsprechend dem momentanen Wert der Variable i benutzt GPI, WS 07/08 195 Deklaration von Arrays Universität Paderborn Prof. Dr. Heike Wehrheim In Java sind Arrays Objekte, die vom new-Operator erzeugt werden Später genauer Deklarationen von Variablen für Arrays: Schema: Array-Typ varname = new Elementtyp [Elementanzahl] Beispiel: int [] noten = new int [100]; double [] messergebnisse = new double[800]; GPI, WS 07/08 196 Initialisierung von Arrays Universität Paderborn Prof. Dr. Heike Wehrheim Auch Initialisierung der Elemente möglich (new, Typ und Anzahl implizit): int [] gewicht = { 5, 10, 5, 15, 15, 50 }; Arrayliteral 5 10 5 15 15 50 gewicht double [] messung = {6.5, 7.8, -2.4, 10} 6.5 7.8 -2.4 10 messung GPI, WS 07/08 197 Universität Paderborn Prof. Dr. Heike Wehrheim Indizierung Zugriff auf Elemente des Arrays gewicht[i] mit i = 0,...,(gewicht.length-1) Achtung: Index fängt bei 0 an! gewicht.length: Anzahl der Elemente des Arrays in der Variablen gewicht. 0 5 1 2 10 5 3 4 5 15 15 50 gewicht gewicht[0] – 5 gewicht[4] – 15 gewicht[6] – Fehler: ArrayIndexOutOfBoundsException GPI, WS 07/08 198 Zuweisung auf Feldelemente Universität Paderborn Prof. Dr. Heike Wehrheim Zuweisen eines Wertes an ein Element: gewicht 5 10 5 15 15 50 gewicht[3] = 7; gewicht 5 10 5 7 15 50 gewicht[0] = gewicht[5]; gewicht 50 10 5 GPI, WS 07/08 7 15 50 199 Beispiel 1 Universität Paderborn Prof. Dr. Heike Wehrheim Alle Noten um eine Stufe erhöhen int [] noten = new int [100]; // irgendwo mit Werten belegen Nicht: i <= noten.length! for (int i = 0;i < noten.length; i++) { noten[i] = noten[i] + 1; } GPI, WS 07/08 200 Beispiel 2 Universität Paderborn Prof. Dr. Heike Wehrheim Den Durchschnitt der Noten von GP1 und GP2 ermitteln: int [] gp1 = new int [400]; int [] gp2 = new int [400]; double [] durchschnitt = new double [400]; /* ergebnisse werden irgendwo eingegeben */ for (int i = 0; i < gp1.length; i++){ durchschnitt[i] = (gp1[i] + gp2[i]) / 2.0; } GPI, WS 07/08 201 Beispiel 3 Universität Paderborn Prof. Dr. Heike Wehrheim Ausdrucken von Arrays Algorithmenidee: For-Schleife zum Durchlaufen, jedes Element drucken; nach jeweils 5 Elementen einen Zeilenvorschub for (int i = 0; i < arr.length; i++) { if (i%5 == 0) System.out.println(); System.out.print(arr[i]+" "); }; System.out.println(); GPI, WS 07/08 202 Beispiel 4 Universität Paderborn Prof. Dr. Heike Wehrheim args: Ein Array von Strings … public static void main (String [] args) { int zahl1 = Integer.parseInt(args[0]); int zahl2 = Integer.parseInt(args[1]); … das 0-te Element das 1-te Element GPI, WS 07/08 203 Universität Paderborn Prof. Dr. Heike Wehrheim Eigene Aufgabe Summe der Elemente eines int Arrays der Länge 6 berechnen int [] zahlen = new int[6]; kann als gegeben angesehen werden ArrayAufsummieren.java GPI, WS 07/08 204 Universität Paderborn Prof. Dr. Heike Wehrheim Zuweisung an Array-Variablen Einer Array-Variablen kann der Wert eines ArrayAusdrucks des gleichen Typs zugewiesen werden int [] v = {1,2,3,4}; int [] w = new int[4]; w = v; 1 2 3 4 v w GPI, WS 07/08 205 Achtung Universität Paderborn Prof. Dr. Heike Wehrheim Mit new wird ein neues Feld des entsprechenden Typs angelegt Bei der Zuweisung dieses Feldes an eine Arrayvariable wird ein Verweis (Referenz) von der Variablen auf das Feld gesetzt (wie bei Initialisierung) Bei der Zuweisung eines Feldes an eine Arrayvariable wird das Feld nicht kopiert GPI, WS 07/08 206 Was passiert hier? Universität Paderborn Prof. Dr. Heike Wehrheim int [] a = { 1, 1, 1}; int [] b; b = a; b[2] = 4; System.out.println(a[2]); Wie ist die Ausgabe? GPI, WS 07/08 207 Und wenn ich eine Kopie brauche? Universität Paderborn Prof. Dr. Heike Wehrheim Kopieren durch explizite Kopie der Elemente int [] v = int [] w = for (int i w[i] = } GPI, WS 07/08 {1,2,3,4}; new int[v.length]; = 0; i < v.length; i++) { v[i]; 208 Sieb des Erathostenes Universität Paderborn Prof. Dr. Heike Wehrheim Ziel: Berechnung aller Primzahlen bis zu einer Obergrenze n Prinzip des Algorithmus: 1. Lege eine Tabelle mit allen Zahlen von 2 bis n an 2. Streichen von Zahlen aus der Tabelle a. Wähle die erste Zahl, die noch nicht gestrichen worden ist b. Streiche alle echten Vielfachen dieser Zahl aus der Tabelle c. Wähle die nächste noch nicht gestrichene zahl aus und mache mit b weiter GPI, WS 07/08 209 Wie machen wir das? Universität Paderborn Prof. Dr. Heike Wehrheim Streichen: statt Array mit Zahlen von 2 bis n, Array der Länge n+1 mit booleschen Werten true -> (noch) nicht gestrichen false -> gestrichen Index des Arrays (von 0 bis n) gibt uns die Zahl selber Vielfache einer Zahl z streichen: Starten mit 2*z -> Streichen -> erhöhen um z -> Streichen, erhöhen um z -> Streichen, … bis n erreicht ist (Wieviele Schleifen brauchen wir wohl?) GPI, WS 07/08 210 In Java Universität Paderborn Prof. Dr. Heike Wehrheim public class SiebEra { SiebEra.java public static void main (String [] args) { // Einlesen von n int n = Integer.parseInt(args[0]); // Tabelle erstellen, noch nichts gestrichen boolean [] tabelle = new boolean[n+1]; for (int i = 2; i <= n; i++) tabelle[i] = true; // Tabelle bearbeiten for (int naechste = 2; naechste <= n; naechste++) { if (tabelle[naechste]) { // noch nicht gestrichen? System.out.println(naechste); // Streichen der Vielfachen for (int i = 2 * naechste; i <= n; i+= naechste) tabelle[i] = false; }}}} GPI, WS 07/08 211 3. Anwendungsmuster Schleifen Universität Paderborn Prof. Dr. Heike Wehrheim Suchschleife: Die Elemente eines Feldes werden durchsucht, bis das Gesuchte gefunden wurde oder alle Elemente vergeblich durchsucht worden sind Die Schleife hat 2 verschiedenartige Ergebnisse: gefunden oder Feld ist fertig durchsucht Sie müssen nach der Schleife unterschiedlich behandelt werden. Die Schleifenbedingung lautet: nicht gefunden und Feld noch nicht vollständig durchsucht GPI, WS 07/08 212 Beispiel Universität Paderborn Prof. Dr. Heike Wehrheim Gibt es einen Studenten, der mit 100 Punkten bestanden hat? boolean gefunden = false; int [] noten = new int[400] ; // Noten werden eingelesen Kein For: wir wollen abbrechen, wenn gefunden int i = 0; while (!gefunden && i < noten.length) { if (noten[i] == 100) gefunden = true; else i++; } if (! gefunden) System.out.println(„Kein Student hat mit 100 Punkten bestanden.“); else System.out.println(„(Mindestens) ein Student hat mit 100 Punkten bestanden“); GPI, WS 07/08 213 Mehrdimensionale Arrays Universität Paderborn Prof. Dr. Heike Wehrheim Der Elementtyp ist wieder ein Array-Typ Beispiel: int [][] matrix = new int [2][3]; Zugriff: matrix [i][j] matrix GPI, WS 07/08 214 Universität Paderborn Prof. Dr. Heike Wehrheim Mehrdimensionale Arrays Initialisierung: int[][] matrix ={{1,2,3},{4,5,6}}; z.B. matrix[0][2] -> 3 matrix[1][0] -> 4 matrix GPI, WS 07/08 1 2 3 4 5 6 215 Beispiel Universität Paderborn Prof. Dr. Heike Wehrheim Matrizenaddition: A, B Matrizen C = A + B definiert durch C(i,j) = A(i,j) + B(i,j) Struktur des Algorithmus: FÜR jede Zeile FÜR jede Spalte … jeweilige Einträge aufsummieren … GPI, WS 07/08 216 In Java Universität Paderborn Prof. Dr. Heike Wehrheim int [] [] matrix1, matrix2 = new int[10][2]; // Matrizen werden gefüllt … int zeilen = matrix1.length; int spalten = matrix1[0].length; int[][] ergebnis = new int[zeilen][spalten]; for (int i = 0; i < zeilen; i++) { for (int j = 0; j < spalten ; j++) { ergebnis[i][j] = matrix1[i][j] + matrix2[i][j]; } } GPI, WS 07/08 217 Zugriff auf Array-Elemente Universität Paderborn Prof. Dr. Heike Wehrheim Auf einem Element eines Feldes sind alle Operationen möglich, die auf einer Variable des entsprechenden Typs möglich sind double [][] matrix; double [] vektor; matrix[0][1] hat Typ double matrix[0] hat Typ double[] vektor hat Typ double[] vektor[2] hat Typ double GPI, WS 07/08 218 Beispiel Universität Paderborn Prof. Dr. Heike Wehrheim Vertauschen der Zeilen i und j einer Tabelle: double[][] tabelle = new double [4][3]; double[] zeile; zeile = tabelle[i]; tabelle[i] = tabelle[j]; tabelle[j] = zeile; GPI, WS 07/08 219 Eigene Aufgabe Universität Paderborn Prof. Dr. Heike Wehrheim Alle Studenten (Matrikelnummern 0,1,2, …) schreiben n Klausuren (0,1, …). Die Ergebnisse davon (bestanden/nicht bestanden) seien in einer Tabelle abgelegt. Schreiben Sie ein Programm, das ermittelt, welcher Student am Besten abgeschnitten hat. (Sollte es mehrere gleichgute geben, wird der erste dieser Studenten ausgegeben) GPI, WS 07/08 220 Lösung Universität Paderborn Prof. Dr. Heike Wehrheim boolean [] [] noten = { {true, false, false, false}, {false, true, false, true}, {true, true, true, false}, {false, false, false, false}, {true, true, true, false}}; int bester = 0; // Index des besten int besterBestanden = 0; // Anzahl der bestandenen Prüfungen des besten int aktuellBestanden; // Anzahl der bestandenen Prüfungen des aktuellen for (int i = 0; i < noten.length; i++) { aktuellBestanden = 0; for (int j = 0; j < noten[i].length; j++) { if (noten[i][j]) // bestanden? Klausurauswerter.java aktuellBestanden++; } if (aktuellBestanden > besterBestanden) { besterBestanden = aktuellBestanden; bester = i; }} System.out.println("Der beste Student ist " + bester + " mit " + besterBestanden + " Klausuren"); GPI, WS 07/08 221