• Keine Ergebnisse gefunden

252-0027 Einführung in die Programmierung 5.0 Input/Output

N/A
N/A
Protected

Academic year: 2022

Aktie "252-0027 Einführung in die Programmierung 5.0 Input/Output"

Copied!
95
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

252-0027

Einführung in die Programmierung 5.0 Input/Output

Thomas R. Gross

Department Informatik ETH Zürich

1

(2)

Übersicht

§ 5.1 Output in Fenster

§ 5.2 Arbeiten mit Dateien

§ 5.3 Scanner im Einsatz/Beispiele

(3)

Input (soweit mit Scanner)

§ Folge von Zeichen die der Scanner liest: Token

§ Input Element

§ Erwartete Zeichen hängen von Methode (z.B. nextDouble()) ab

§ Scanner zerlegt den Inhalt einer File in Tokens

3

(4)
(5)

Input Tokens

§ Wenn eine Input File diese Zeichen (Buchstaben) enthält:

23 3.14

"John Smith"

§ Dann kann der Scanner die Tokens als Input verschiedener Typen interpretieren:

Token Type(s)

23 int, double, String

3.14 double, String

"John String

Smith" String

5

(6)

Files und der Input Cursor (Zeiger)

§ Nehmen wir an, eine Datei weather.txt enthält diesen Text:

16.2 23.5

19.1 7.4 22.8

18.5 -1.8 14.9

§ Für den Scanner ist jeder Input eine Folge von Buchstaben:

16.2 23.5\n19.1 7.4 22.8\n\n18.5 -1.8 14.9\n

^

§ ^ ist der input cursor: die augenblickliche Position des Scanners.

(7)

Verarbeiten einer Input File

§ Der Scanner identifiziert ein Token

§ Das Token wird gelesen und an den Aufrufer des Scanners abgeliefert

§ Annahme: keine Fehler

§ Dabei wird der Cursor über die gelesenen Buchstaben geführt

§ Wir sagen der Scanner konsumiert das Token

7

(8)

Konsumieren von Input

§ Konsumieren von Tokens: Input lesen und dabei Cursor weiter bewegen

§ Aufruf von nextInt , nextDouble , etc. bewegt den Cursor hinter das aktuelle Token.

16.2 23.5\n19.1 7.4 22.8\n\n18.5 -1.8 14.9\n

^

§ Die Datei wird dabei nicht verändert

(9)

Konsumieren von Input, Teil 2

§ Aufruf von nextInt, nextDouble, etc. bewegt den Cursor hinter das aktuelle Token.

16.2 23.5\n19.1 7.4 22.8\n\n18.5 -1.8 14.9\n

^

double d = input.nextDouble(); // 16.2

16.2 23.5\n19.1 7.4 22.8\n\n18.5 -1.8 14.9\n

^

String s = input.next(); // "23.5"

16.2 23.5\n19.1 7.4 22.8\n\n18.5 -1.8 14.9\n

^

9

(10)

File Input Aufgabe

§ Zurück zur File mit Wetter Daten

§ Schreiben Sie ein Programm das den Temperaturunterschied

zwischen zwei aufeinander folgenden Tagen berechnet.

16.2 23.5

19.1 7.4 22.8

18.5 -1.8 14.9

16.2 to 23.5, change = 7.3 23.5 to 19.1, change = -4.4 19.1 to 7.4, change = -11.7 7.4 to 22.8, change = 15.4 22.8 to 18.5, change = -4.3 18.5 to -1.8, change = -20.3 -1.8 to 14.9, change = 16.710

(11)

File Input Antwort

// Displays changes in temperature from data in an input file.

import java.io.*; // for File import java.util.*; // for Scanner

public class Temperatures {

public static void main(String[] args) throws FileNotFoundException {

Scanner input = new Scanner(new File("weather.txt"));

double prev = input.nextDouble(); // fencepost for (int i = 1; i <= 7; i++) {

double next = input.nextDouble();

System.out.println(prev + " to " + next +

", change = " + (next - prev));

prev = next;

} }

}

11

(12)

Lesen einer ganzen File

§ Nehmen wir an unser Programm sollte für eine beliebige Anzahl von Zahlen in der Datei funktionieren.

§ Bis jetzt wurden zusätzliche Daten nicht gelesen.

§ Wenn die Datei weniger Daten enthält – was passiert dann?

Ein Laufzeitfehler! Beispiel mit einer Datei mit 3 Zahlen:

16.2 to 23.5, change = 7.3 23.5 to 19.1, change = -4.4

Exception in thread "main" java.util.NoSuchElementException at java.util.Scanner.throwFor(Scanner.java:838)

at java.util.Scanner.next(Scanner.java:1347)

at Temperatures.main(Temperatures.java:12) 12

(13)

Scanner Exceptions

§ NoSuchElementException

§ Versuch über das Ende der Datei hinauszulesen

§ InputMismatchException

§ Versuch den falschen Type von Daten zu lesen (z.B. lesen von "hi"

als int).

13

(14)

Scanner Exceptions

§ Entschlüsseln und Beheben dieser Exceptions:

§ Finden Sie die Stelle im ExceptionText, die sich auf eine Zeile Ihres Programms bezieht

(erste Zeile die sich auf Ihr Programm bezieht; oft gegen Ende der Fehlermeldung):

Exception in thread "main"

java.util.NoSuchElementException

at java.util.Scanner.throwFor(Scanner.java:838) at java.util.Scanner.next(Scanner.java:1347)

at MyProgram.myMethodName(MyProgram.java:19) at MyProgram.main(MyProgram.java:6)

(15)

Scanner Tests

§ Diese Methoden prüfen ob gültiger Input vorliegt

§ Diese Scanner Methoden konsumieren keinen Input, sie lieferen nur Information über das nächste Token.

§ Praktisch um vorauszusehen was für Input kommt um so Laufzeitfehler zu verhindern.

Method Description

hasNext() returns true if there is a next token hasNextInt() returns true if there is a next token

and it can be read as an int

hasNextDouble() returns true if there is a next token and it can be read as a double

15

(16)

Gebrauch der hasNext Methode

§ Zur Vermeidung von Leseaktionen mit einem unpassenden Typ:

Scanner console = new Scanner(System.in);

System.out.print("How old are you? ");

if (console.hasNextInt()) {

int age = console.nextInt(); // will not crash!

System.out.println("Wow, " + age + " is old!");

} else {

System.out.println("You didn't type an integer.");

}

(17)

Gebrauch der hasNext Methode

§ Um nicht über das Ende einer Datei hinauszulesen:

Scanner input = new Scanner(new File("example.txt"));

if (input.hasNext()) {

String token = input.next(); // will not crash!

System.out.println("next token is " + token);

}

17

(18)

File Input Aufgabe 2

§ Verändern Sie das Temperatur Programm, so dass es die gesamte File verarbeitet, unabhängig von der Anzahl der Datensätze in der File.

§ Beispiel: Mit Daten für den 9. Tag wäre der Output:

16.2 to 23.5, change = 7.3 23.5 to 19.1, change = -4.4 19.1 to 7.4, change = -11.7 7.4 to 22.8, change = 15.4 22.8 to 18.5, change = -4.3 18.5 to -1.8, change = -20.3 -1.8 to 14.9, change = 16.7

14.9 to 16.1, change = 1.2

18

(19)

File Input Lösung 2

// Displays changes in temperature from data in an input file.

import java.io.*; // for File import java.util.*; // for Scanner

public class Temperatures {

public static void main(String[] args) throws FileNotFoundException {

Scanner input = new Scanner(new File("weather.txt"));

double prev = input.nextDouble(); // fencepost while (input.hasNextDouble()) {

double next = input.nextDouble();

System.out.println(prev + " to " + next +

", change = " + (next - prev));

prev = next;

} }

} 19

(20)

File Input Aufgabe 3

§ Modifizieren Sie das Temperatur Programm so dass es auch dann funktioniert wenn die Input Datei nicht-numerische Tokens enthält.

§ Diese sollten ignoriert werden

§ Für die Input File weather2.txt sollte das Programm den selben Output lieferen wie vorher

16.2 23.5

Dienstag 19.1 Mittwoch 7.4 Do.Wert: 22.8

18.5 -1.8 <-- Messfehler??? --Stefan P. 14.9 :-)

§ Sie können davon ausgehen dass das 1. Token eine reelle Zahl ist.

20

(21)

File Input Lösung 3

// Displays changes in temperature from data in an input file.

import java.io.*; // for File import java.util.*; // for Scanner public class Temperatures2 {

public static void main(String[] args) throws FileNotFoundException {

Scanner input = new Scanner(new File("weather.txt"));

double prev = input.nextDouble(); // fencepost while (input.hasNext()) {

if (input.hasNextDouble()) {

double next = input.nextDouble();

System.out.println(prev + " to " + next +

", change = " + (next - prev));

prev = next;

} else {

input.next(); // throw away unwanted token }

}

} } 21

(22)

File Input Lösung 3

// Displays changes in temperature from data in an input file.

import java.io.*; // for File import java.util.*; // for Scanner public class Temperatures2 {

public static void main(String[] args) throws FileNotFoundException {

Scanner input = new Scanner(new File("weather.txt"));

double prev = input.nextDouble(); // fencepost while (input.hasNext()) {

if (input.hasNextDouble()) {

double next = input.nextDouble();

System.out.println(prev + " to " + next +

", change = " + (next - prev));

prev = next;

} else {

input.next(); // throw away unwanted token }

}

} } 22

(23)

Ein weiteres Problem (Arbeitszeit berechnen)

§ Die File hours.txt enthält die folgenden Daten:

123 Paula 12.5 8.1 7.6 3.2

456 Erich 4.0 11.6 6.5 2.7 12 789 Steffie 8.0 8.0 8.0 8.0 7.5

§ Wir wollen ein Programm schreiben das die Anzahl Stunden für jede Person berechnet:

Paula (ID#123) worked 31.4 hours (7.85 hours/day)

Erich (ID#456) worked 36.8 hours (7.36 hours/day)

Steffie (ID#789) worked 39.5 hours (7.9 hours/day)

23

(24)

Ein weiteres Problem (HoursWorked)

§ Fangen wir mit den Token an und behandeln jedes Token …

(25)

Lösungsversuch Stundenberechnung

// Let’s try to fill in the body …

import java.io.*; // for File

import java.util.*; // for Scanner public class HoursWorked {

public static void main(String[] args) throws FileNotFoundException {

Scanner input = new Scanner(new File("hours.txt"));

while (input.hasNext()) {

} }

} 25

(26)

(Fehlerhafte) Lösung zur Stundenberechnung

// This solution does not work!

while (input.hasNext()) { // process one person

int id = input.nextInt();

String name = input.next();

double totalHours = 0.0;

int days = 0;

while (input.hasNextDouble()) {

totalHours += input.nextDouble();

days++;

}

System.out.println(name + " (ID#" + id + ") worked " + totalHours + " hours (” + (totalHours / days) +

" hours/day)");

}

(27)

(Fehlerhafte) Lösung zur Stundenberechnung

// This solution does not work!

while (input.hasNext()) { // process one person

int id = input.nextInt();

String name = input.next();

double totalHours = 0.0;

int days = 0;

while (input.hasNextDouble()) {

totalHours += input.nextDouble();

days++;

}

System.out.println(name + " (ID#" + id + ") worked " + totalHours + " hours (” + (totalHours / days) +

" hours/day)");

} 28

123 Paula

12.5 8.1 7.6 3.2 456

Erich

True True True True True False

(28)

Fehlerhafter Output

Paula (ID#123) worked 487.4 hours (97.48 hours/day)

Exception in thread "main"

java.util.InputMismatchException

at java.util.Scanner.throwFor(Scanner.java:840) at java.util.Scanner.next(Scanner.java:1461)

at java.util.Scanner.nextInt(Scanner.java:2091) at HoursWorked.main(HoursBad.java:9)

(29)

Fehlerhafter Output

§ Etwas lief falsch …

§ Die innere while Schleife hat die Personalnummer der nächsten Person gelesen.

§ Wir wollen die Tokens verarbeiten aber wir wollen auch wissen, wo eine Zeile endete (\n sagt an wann die Daten für eine Person

abgeschlossen sind).

§ Eine bessere Lösung basiert auf einem hybriden Ansatz:

§ Zuerst: zerlege den Input in Zeilen.

§ Dann zerlege jede Zeile in Tokens.

30

(30)

Zeilen-basierte Scanner Aktivität

Scanner input = new Scanner(new File("file name"));

while (input.hasNextLine()) {

String line = input.nextLine();

process this line;

}

Method Description

nextLine() returns next entire line of input (from cursor to \n)

hasNextLine() returns true if there are any more lines of input to read (always true for console input)

(31)

Verarbeiten von Input Zeilen

23 3.14 John Smith "Hello" world 45.2 19

§ Der Scanner liest die Zeilen folgendermassen:

23\t3.14 John Smith\t"Hello" world\n\t\t45.2 19\n

^

String line = input.nextLine();

23\t3.14 John Smith\t"Hello" world\n\t\t45.2 19\n

^

§ Jedes \n Zeichen wird konsumiert aber nicht an die aufrufende

Methode übergeben.

32

(32)

Verarbeiten von Input Zeilen

23 3.14 John Smith "Hello" world 45.2 19

Line: 23\t3.14 John Smith\t"Hello" world

§ Der Scanner liest die Zeilen folgendermassen weiter:

String line2 = input.nextLine();

23\t3.14 John Smith\t"Hello" world\n\t\t45.2 19\n

^

§ Vorsicht: Jedes \n Zeichen wurde konsumiert aber nicht an die

aufrufende Methode übergeben.

(33)

Scanner für Strings

§ Ein Scanner kann auch die Tokens in einem String finden:

Scanner name = new Scanner(String);

§ Beispiel:

String text = "15 3.2 hello 9 27.5";

Scanner scan = new Scanner(text);

int num = scan.nextInt();

System.out.println(num); // 15 double num2 = scan.nextDouble();

System.out.println(num2); // 3.2 String word = scan.next();

System.out.println(word); // hello

34

(34)

Zeilen und Tokens

// Counts the words on each line of a file

Scanner input = new Scanner(new File("input.txt"));

while (input.hasNextLine()) {

String line = input.nextLine();

Scanner lineScan = new Scanner(line);

// process the contents of this line

}

Input file input.txt: Output to console:

The quick brown fox jumps over the lazy dog.

Line has 6 words Line has 3 words

(35)

// Counts the words on each line of a file

Scanner input = new Scanner(new File("input.txt"));

while (input.hasNextLine()) {

String line = input.nextLine();

Scanner lineScan = new Scanner(line);

// process the contents of this line int count = 0;

while (lineScan.hasNext()) {

String word = lineScan.next();

count++;

}

System.out.println("Line has " + count + " words");

}

36

(36)

Zurück zur Aufgabe, die Stunden zu berechnen

§ Verbessern Sie das HoursWorked Program so, dass es die Input File richtig liest:

123 Paula 12.5 8.1 7.6 3.2

456 Erich 4.0 11.6 6.5 2.7 12 789 Steffi 8.0 8.0 8.0 8.0 7.5

§ Gewünschter Output:

Paula (ID#123) worked 31.4 hours (7.85 hours/day)

Erich (ID#456) worked 36.8 hours (7.36 hours/day)

Steffi (ID#789) worked 39.5 hours (7.9 hours/day)

(37)

(Fehlerhafte) Lösung zur Stundenberechnung

// This solution does not work!

while (input.hasNext()) { // process one person

int id = input.nextInt();

String name = input.next();

double totalHours = 0.0;

int days = 0;

while (input.hasNextDouble()) {

totalHours += input.nextDouble();

days++;

}

System.out.println(name + " (ID#" + id + ") worked " + totalHours + " hours (” + (totalHours / days) +

" hours/day)");

} 38

(38)
(39)

// Processes an employee input file and outputs each employee's hours.

import java.io.*; // for File import java.util.*; // for Scanner

public class Hours {

public static void main(String[] args) throws FileNotFoundException { Scanner input = new Scanner(new File("hours.txt"));

while (input.hasNextLine()) {

String line = input.nextLine();

Scanner lineScan = new Scanner(line);

int id = lineScan.nextInt(); // e.g. 456

String name = lineScan.next(); // e.g. "Erich"

double sum = 0.0;

int count = 0;

while (lineScan.hasNextDouble()) {

sum = sum + lineScan.nextDouble();

count++;

} 40

(40)

while (input.hasNextLine()) {

String line = input.nextLine();

Scanner lineScan = new Scanner(line);

int id = lineScan.nextInt(); // e.g. 456

String name = lineScan.next(); // e.g. "Erich"

double sum = 0.0;

int count = 0;

while (lineScan.hasNextDouble()) {

sum = sum + lineScan.nextDouble();

count++;

}

double average = sum / count;

System.out.println(name + " (ID#" + id + ") worked " + sum + " hours (" + average + " hours/day)");

} }

} 41

(41)

File Output

42

(42)

Output für Files

§ PrintStream : Ein Objekt aus java.io das es erlaubt, Daten auszugeben (z.B. in eine File).

§ Alle Methoden die wir mit System.out (wie z.B. print,

println) verwendet haben, funktionieren auch für PrintStream Objekte.

§ Syntax:

PrintStream name = new PrintStream(new File("file name"));

(43)

Output für Files

§ Syntax:

PrintStream name = new PrintStream(new File("file name"));

Example:

PrintStream output = new PrintStream(new File("out.txt"));

output.println("Hello, file!");

output.println("This is a second line of output.");

44

(44)

Mehr über PrintStream

PrintStream name = new PrintStream(new File("file name"));

§ Falls keine File mit diesem Namen existiert so wird sie kreiert.

§ Sollte die File schon existieren so wird sie überschrieben.

§ Der Output den das Programm produziert erscheint in einer File, nicht im Konsole Fenster.

Sie müssen einen Editor (o. ä.) verwenden um den Inhalt zu sehen.

(45)

Mehr über PrintStream

PrintStream name = new PrintStream(new File("file name"));

§ Arbeiten Sie nicht mit der selben File als Input (Lesen durch Scanner) und Output (Schreiben mit PrintStream) zur selben Zeit!

§ Sie überschreiben die Input File und ersetzen sie durch eine leere File (0 Byte).

46

(46)

System.out und PrintStream

§ Das Objekt für Konsolenoutput, System.out, ist ein PrintStream.

PrintStream out1 = System.out;

PrintStream out2 = new PrintStream(new File("data.txt"));

out1.println("Hello, console!"); // goes to console out2.println("Hello, file!"); // goes to file

§ Ein Verweis (Reference) auf System.out kann in einer Variablen vom Typ a PrintStream gespeichert werden.

§ Print Methoden (für diese Variable) lassen dann Output erscheinen.

(47)

PrintStream Aufgabe

§ Modifieren Sie die vorherige Version von Hours so dass es einen PrintStream verwendet um Output in die File

hours_out.txt zu schreiben

§ Das Programm soll keinen Konsolen Output produzieren.

§ Aber die Datei hours_out.txt soll erschaffen werden und diesen Text enthalten:

Paula(ID#123) worked 31.4 hours (7.85 hours/day)

Erich (ID#456) worked 36.8 hours (7.36 hours/day)

Steffi (ID#789) worked 39.5 hours (7.9 hours/day)

48

(48)

PrintStream Lösung

// Processes an employee input file and outputs each employee's hours.

import java.io.*; // for File import java.util.*; // for Scanner

public class Hours2 {

public static void main(String[] args) throws FileNotFoundException { Scanner input = new Scanner(new File("hours.txt"));

PrintStream out = new PrintStream(new File("hours_out.txt"));

while (input.hasNextLine()) {

String line = input.nextLine();

Scanner lineScan = new Scanner(line);

int id = lineScan.nextInt(); // e.g. 456 String name = lineScan.next(); // e.g. "Eric"

double sum = 0.0;

int count = 0;

// while

(49)

PrintStream Lösung

while (lineScan.hasNextDouble()) {

sum = sum + lineScan.nextDouble();

count++;

}

double average = sum / count;

out.println(name + " (ID#" + id + ") worked " +

sum + " hours (" + average + " hours/day)");

} }

}

50

(50)

Beispiel: Filenamen als User Input

§ Wir können den Namen der File, die gelesen werden soll, vom Benutzer erfragen.

§ Der Name der File könnte Leerzeichen enthalten; verwenden Sie nextLine() , nicht next()

// prompt for input file name

Scanner console = new Scanner(System.in);

System.out.print("Type a file name to use: ");

String filename = console.nextLine();

Scanner input = new Scanner(new File(filename));

(51)

52

(52)

Beispiel: Filenamen als User Input

§ Die Klasse File stellt eine exists Methode zur Verfügung um zu testen ob der Filename sich auf eine File bezieht

(verhindert file-not-found Exception später):

File file = new File("hours.txt");

if (!file.exists()) {

// try a second input file as a backup

System.out.print("hours.txt file not found!");

file = new File("hours2.txt");

}

(53)

Tokens und Zeilen

§ Vorsicht bei der Verwendung von nextLine wenn auch Token-basierte Methoden für den selben Scanner

verwendet werden.

23 3.14

Joe "Hello" world 45.2 19

§ Wir sehen einen int Wert, einen double Wert und dann eine Zeile Text.

54

(54)

Tokens und Zeilen

§ Hier ist ein erster Versuch:

§ Wir (versuchen) 23 und 3.14 mit nextInt und nextDouble zu lesen und wollen dann Joe "Hello" world mit nextLine lesen.

System.out.println(input.nextInt()); // 23 System.out.println(input.nextDouble()); // 3.14 System.out.println(input.nextLine()); //

§ Aber der Aufruf von nextLine liefert keinen Output! Warum?

(55)

Tokens und Zeilen

§ Sie sollten nicht Tokens und Zeilen vom selben Scanner lesen:

23 3.14

Joe "Hello" world

45.2 19

input.nextInt() // 23 23\t3.14\nJoe\t"Hello" world\n\t\t45.2 19\n

input.nextDouble()^ // 3.14

23\t3.14\nJoe\t"Hello" world\n\t\t45.2 19\n

^

input.nextLine() // "" (empty!) 23\t3.14\nJoe\t"Hello" world\n\t\t45.2 19\n

input.nextLine()^ // "Joe\t\"Hello\" world"

23\t3.14\nJoe\t"Hello" world\n\t\t45.2 19\n

^

56

(56)

Beispiel

Scanner console = new Scanner(System.in);

System.out.print("Enter your age: ");

int age = console.nextInt();

System.out.print("Now enter your name: ");

String name = console.nextLine();

System.out.println(name + " is " + age + " years old.");

(57)

Beispiel Fortsetzung

§ Protokoll der Ausführung (Benutzer Eingabe unterstrichen):

Enter your age: 12

Now enter your name: Sideshow Bob is 12 years old.

§ Warum?

§ Input insgesamt: 12\nSideshow Bob

§ Nach nextInt(): 12\nSideshow Bob

^

§ Nach nextLine(): 12\nSideshow Bob

^

58

(58)
(59)

252-0027

Einführung in die Programmierung

6.0 Arbeiten mit Objekten und Klassen

Thomas R. Gross

Department Informatik ETH Zürich

Copyright (c) Pearson 2013. and Thomas Gross 2016

All rights reserved. 1

(60)

Übersicht

6.1 Einleitung – Datenstrukturen mit Verknüpfungen 6.2 Entwurf von (abgekapselten) Klassen

6.3 Hinweise (und Regeln) für verständliche Programme

Copyright (c) Pearson 2013 and Thomas Gross 2016,2017,2019.

(61)

6.1 Einleitung

3

(62)

Datenstrukturen mit Verküpfungen

§ Bisher hatten wir Arrays als Datenstruktur kennen gelernt

§ Ein Array besteht aus Elementen eines Typs int[] ia = {42, -3, 17, 9}

§ Grösse muss im Voraus bekannt sein (new int[length])

§ Oft wollen wir mit einer unbestimmten Anzahl von Elementen arbeiten.

42 -3 17 9

(63)

5

(64)

Datenstrukturen mit Verküpfungen

§ Bisher hatten wir Arrays als Datenstruktur kennen gelernt

§ Grösse muss im Voraus bekannt sein

§ Oft wollen wir mit einer unbestimmten Anzahl von Elementen arbeiten.

§ Diese können wir als verknüpfte Objekte (“linked objects”) organisieren. Jedes Objekt (Knoten) speichert ein Element und einen Verweis auf einen anderen Knoten.

42 -3 17 9

list 42 -3 17 9

?

6

(65)

Datenstrukturen mit Verküpfungen

§ Bisher hatten wir Arrays als Datenstruktur kennen gelernt

§ Grösse muss im Voraus bekannt sein

§ Oft wollen wir mit einer unbestimmten Anzahl von Elementen arbeiten.

§ Diese können wir als verknüpfte Objekte (“linked objects”) organisieren. Jedes Objekt (Knoten) speichert ein Element und einen Verweis auf einen anderen Knoten.

42 -3 17 9

list 42 -3 17 9 null

7

(66)

Datenstrukturen mit Verküpfungen

§ Bisher hatten wir Arrays als Datenstruktur kennen gelernt

§ Grösse muss im Voraus bekannt sein

§ Oft wollen wir mit einer unbestimmten Anzahl von Elementen arbeiten.

§ Diese können wir als verknüpfte Objekte (“linked objects”) organisieren. Jedes Objekt (Knoten) speichert ein Element und einen Verweis auf einen anderen Knoten.

42 -3 17 9

list 42 -3 17 9

(67)

Eine Klasse für Knoten einer Liste

public class ListNode { int data;

??? next;

§ Jeder Knoten der Liste speichert: }

§ Den Wert einer ganzen (int) Zahl

§ Einen Verweis auf einen anderen Listenknoten

§ ListNode s können zu einer Kette verbunden (“linked”) wer- den um eine Menge oder Liste von Werten zu speichern.

data next 42

data next -3

data next 17

data next 9

9

(68)

Eine Klasse für Knoten einer Liste

public class ListNode { int data;

ListNode next;

§ Jeder Knoten der Liste speichert: }

§ Den Wert einer ganzen (int) Zahl

§ Einen Verweis auf einen anderen Listenknoten

§ ListNode s können zu einer Kette verbunden (“linked”) wer- den um eine Menge oder Liste von Werten zu speichern.

data next 42

data next -3

data next 17

data next 9

(69)

ListNode Klient - Beispiel

public class ConstructList1 {

public static void main(String[] args) { ListNode list = new ListNode();

list.data = 42;

list.next = new ListNode();

list.next.data = -3;

list.next.next = new ListNode();

list.next.next.data = 17;

list.next.next.next = null;

System.out.println(list.data + " " + list.next.data + " " + list.next.next.data);

// 42 -3 17 }

}

data next 42

data next -3

data next

list 17

11

(70)

Konstruktor für Knoten einer Liste

public class ListNode { int data;

ListNode next;

public ListNode(int data) { this.data = data;

this.next = null;

}

public ListNode(int data, ListNode next) { this.data = data;

this.next = next;

}

}

12

(71)

Übung

§ Modifizieren Sie das letzte Klientenprogramm so dass es diese Konstruktoren verwendet.

13

(72)

Übung Lösung -- Beispiel

public class ConstructList1 {

public static void main(String[] args) { ListNode list = new ListNode(42,

new ListNode(-3,

new ListNode(17)));

System.out.println(list.data + " " + list.next.data + " " + list.next.next.data);

// 42 -3 17 }

}

data next 42

data next -3

data next

list 17

(73)

ListNode Klient – mit Konstruktor

public class ConstructList1 {

public static void main(String[] args) {

System.out.println(list.data + " " + list.next.data + " " + list.next.next.data);

// 42 -3 17

} } data next

42

data next -3

data next 17 null

list 15

(74)

Verknüpfte Knoten -- Übungsproblem 1

Welche Folge von Anweisungen verändert dieses Bild:

in dieses?

data next 10

data next

list 20

data next 10

data next

list 20 data next

30

(75)

17

(76)

Verknüpfte Knoten -- Übungsproblem 1

Welche Folge von Anweisungen verändert dieses Bild:

in dieses?

list.next.next = new ListNode(30);

data next 10

data next

list 20

data next 10

data next

list 20 data next

30

(77)

Verknüpfte Knoten -- Übungsproblem 2

Welche Folge von Anweisungen verändert dieses Bild:

in dieses?

data next 10

data next

list 20

data next 30

data next

list 10 data next

20

19

(78)
(79)

Verknüpfte Knoten -- Übungsproblem 2

Welche Folge von Anweisungen verändert dieses Bild:

in dieses?

data next 10

data next

list 20

data next 30

data next

list 10 data next

20

list = new ListNode(30, list);

21

(80)

Verknüpfte Knoten -- Übungsproblem 3

Welche Folge von Anweisungen verändert dieses Bild:

in dieses?

data next 10

data next

list1 20

data next 30

data next

list2 40

data next 10

data next

list1 30

data next

list2 40

data next 20

(81)

23

(82)

ListNode rest, list1, list2;

rest = list2.next;

list2.next = list1.next;

list1.next = list2;

list2 = rest;

(83)

Zuweisungen mit Referenzvariablen

§ Variable = Wert ;

§ Die Variable (links von = ) ist Attribut eines durch Referenzvariable (z.B. a) bestimmten Objekts

§ Das Attribut kann auch eine Referenzvariable sein (z.B.

ListNode next

)

Speichert dann Verweis auf Objekt (z.B. a.next verweist auf nächstes Element)

§ Der Wert (rechts von = ) kann ein Verweis auf ein Exemplar sein (ein Rechteck, ein Window, ein Element einer Liste, usw)

Typ des Exemplar muss mit Referenzvariable übereinstimmen

25

(84)

Referenzen vs. Objekte

Variable = Wert ;

Für die Liste rechts:

§ a.next = Wert;

heisst anpassen worauf zeigt

§ Variable = a.next;

heisst die Variable setzen so dass sie auf zeigt

data next

a

10 1 data next20

2

1

2

(85)

Referenzen verändern

§ Wenn das Programm sagt:

a.next = b.next;

§ dann heisst das:

§ ”Lasse die Variable a.next auf den selben Wert (Objekt) zeigen wie b.next."

§ Oder, ”Lasse a.next auf den selben Ort wie b.next zeigen."

data next

a 10 data next

20 data next

b 30 data next

40

27

(86)

Verknüpfte Knoten -- Übungsproblem 4

Welche Folge von Anweisungen verändert dieses Bild:

in dieses?

data next 10

data next

list 990

...

data next 10

data next

list 990

...

data next 1000

(87)

Frage über verknüpfte Knoten

§ Nehmen wir an wir haben eine lange Kette von Knoten:

§ Wir wissen nicht wie lang die Kette ist.

§ Wie könnten wir die Werte in allen Knoten ausgeben?

data next 10

data next

list 990

...

data next 20

29

(88)

Algorithmus Pseudocode

§ Fangen wir am Anfang der Liste an, list verweist auf 1. Knoten

§ while (es gibt noch Knoten auszugeben)

§ Gebe den data Wert des Knotens aus

§ Gehe weiter zum nächsten Knoten via das next Attribut.

data next 10

data next

list 990

...

data next 20

(89)

Algorithmus Pseudocode

§ Fangen wir am Anfang der Liste an, list verweist auf 1. Knoten

§ while (es gibt noch Knoten auszugeben):

§ Gebe den data Wert des Knotens aus

§ Gehe weiter zum nächsten Knoten via das next Attribut.

§ Wie wissen wir ob noch Knoten auszugeben sind?

§ Wir haben einen Verweis auf einen Knoten

§ Nach der Ausgabe des letzten Knotens ist sein next Attribute null.

data next 10

data next

list 990

...

data next 20

31

(90)

Algorithmus Pseudocode

§ Fangen wir am Anfang der Liste an, list verweist auf 1. Knoten

§ while (es gibt noch Knoten auszugeben):

§ Gebe den data Wert des Knotens aus

§ Gehe weiter zum nächsten Knoten via das next Attribut.

§ Wie können wir uns durch die Liste arbeiten ?

list = list.next; // is this a good idea?

data next 10

data next

list 990

...

data next 20

(91)

Abarbeiten einer Liste?

§ Ein (schlechter) Weg jeden Wert in der Liste auszugeben :

while (list != null) {

System.out.println(list.data);

list = list.next; // move to next node }

§ Was ist das Problem?

33

(92)

Abarbeiten einer Liste?

§ Ein (schlechter) Weg jeden Wert in der Liste auszugeben :

while (list != null) {

System.out.println(list.data);

list = list.next; // move to next node }

§ Was ist das Problem?

§ (Wir verlieren die Liste während wir sie ausgeben)

data next 10

data next

list 990

...

data next 20

(93)

Eine weitere Referenz: current

§ Wir wollen list nicht verändern. Wir deklarieren eine andere Variable und ändern diese.

§ Eine ListNode Variable ist nicht ein ListNode Objekt

§ … sondern eine Referenz (Verweis) auf ein Objekt

ListNode current = list;

data next 10

data next

list 990

...

data next 20

current

35

(94)

Eine weitere Referenz: current

ListNode current = list;

§ Was passiert wenn wir jetzt diese Anweisung ausführen:

current = current.next;

data next 10

data next

list 990

...

data next 20

current

(95)

Korrektes Durchlaufen einer Liste

§ Der korrekte Weg jeden Wert der Liste auszugeben:

ListNode current = list;

while (current != null) {

System.out.println(current.data);

current = current.next; // move to next node }

§ Das Verändern von current hat keinen Einfluss auf die Liste.

data next 10

data next

list 990

...

data next 20

37

Referenzen

ÄHNLICHE DOKUMENTE

canRead() Gibt true zurück, falls diese Datei gelesen werden kann, sonst false.. getName() Gibt den Namen diese Datei zurück length() Gibt die Dateigrösse, in Bytes, zurück

§ Arbeiten Sie nicht mit der selben File als Input (Lesen durch Scanner) und Output (Schreiben mit PrintStream) zur selben Zeit.. § Sie überschreiben die Input File und ersetzen

In determining the priority of control units which operate multiple devices with different priority rules (for example, a 2821 that attaches both class 2 and class

The selector light pen feature supplies a hand-held, pen-like device that permits an operator of a display station to select fields of data from the display screen

Punching operations, speeds, internal controls, punching in data mode 2, and all other features related to punching are the same as those of the 1442 Card Read Punch Model Nl,

Das Problem ist, acht Damen auf einem Schachbrett so anzuordnen, dass keine die andere

Input port lines and output port lines are accessed at 16-pin DIP sockets on the card.. A reset line is

Transfers the command second word (up to 16-bits) contained in the specified memory location to the peripheral specified in the device (unit)