Folien1 - ETH Zürich

Werbung
Informatik II PVK
Tag 1
Michael Baumann
[email protected]
n.ethz.ch/~mbauman
|
|
Grundsätzliches
●
Alle Materialien verfügbar unter n.ethz.ch/~mbauman
●
Sinn des PVK
●
Kurze Repetition der wichtigen Konzepte
●
Lösen einiger kurzer Aufgaben
●
Tipps zur Prüfung
●
NICHT neues Hintergrundwissen / Zeug aus der
Vorlesung vertiefen
●
●
Ziel: Ihr besteht alle die Prüfung
Informatik ist Übungssache
|
|
2
Themen Theorie
1) Java Basics
2) Theorie: Komplexität und Laufzeit
3) OOP
|
|
3
Themen Praxis
1) Syntaxbäume
2) Verkettete Listen
3) Stacks
4) Binärsuche
5) Suchbäume
6) Spielbäume
7) Backtracking
8) Rekursion & Divide et impera
9) Simulation
10)Heaps
11)Parallelisierung
|
|
4
Java Fundamentals
|
|
5
Java Basics
●
Die (relevanten) Schlüsselwörter
abstract
assert
boolean
break
byte
case
catch
char
class
const
continue
default
do
double
else
enum
extends
final
finally
float
for
goto
if
implements
import
instanceof
int
interface
long
native
new
package
private
protected
public
return
short
static
strictfp
super
switch
synchronized
this
throw
throws
transient
try
void
volatile
while
Unused; Dem C++-const enspricht final
|
|
6
Ein Java-Programm
package demos;
public class Mult {
public static void main(String[] args) {
int i = 5, j = 9;
System.out.println(i + " * " + j + " = " + f(i,j));
}
static int f(int a, int b){
if (b == 1)
return a;
if (b % 2 == 0)
return f(a + a, b / 2);
else
return a + f(a + a, b / 2);
}
}
|
|
7
Ein Java-Programm
package demos;
public class Mult {
public static void main(String[] args) {
int i = 5, j = 9;
System.out.println(i + " * " + j + " = " + f(i,j));
Unser Programm befindet sich
}
im package
static int f(int a, int b){ 'demos'
if (b == 1)
Entspricht in etwa dem C++
return a;
'namespace'
if (b % 2 == 0)
return f(a + a, b / 2);
else
return a + f(a + a, b / 2);
}
}
|
|
8
Ein Java-Programm
package demos;
public class Mult {
public static void main(String[] args) {
int i = 5, j = 9;
System.out.println(i + " * " + j + " = " + f(i,j));
}
public:
static int f(int a, int b){
Die Klasse soll ausserhalb des
if (b == 1)
packages sichtbar sein
return a;
if (b % 2 == 0)
return f(a + a, b / 2);
else
return a + f(a + a, b / 2);
}
}
|
|
9
Ein Java-Programm
package demos;
public class Mult {
public static void main(String[] args) {
int i = 5, j = 9;
System.out.println(i + " * " + j + " = " + f(i,j));
}
static int f(int a, int b){Eine Klasse
if (b == 1)
return a;
if (b % 2 == 0)
return f(a + a, b / 2);
else
return a + f(a + a, b / 2);
}
}
|
| 10
Ein Java-Programm
package demos;
public class Mult {
public static void main(String[] args) {
int i = 5, j = 9;
System.out.println(i + " * " + j + " = " + f(i,j));
}
Nach aussen sichtbare
static int f(int a, int b){
Funktion
if (b == 1)
return a;
if (b % 2 == 0)
return f(a + a, b / 2);
else
return a + f(a + a, b / 2);
}
}
|
| 11
Ein Java-Programm
package demos;
public class Mult {
public static void main(String[] args) {
int i = 5, j = 9;
System.out.println(i + " * " + j + " = " + f(i,j));
static:
}
Funktion existiert pro Klasse,
static int f(int a, int b){
nicht pro Objekt
if (b == 1)
-> Klasse muss nicht instanziiert
return a;
werden
if (b % 2 == 0)
return f(a + a, b / 2);
else
return a + f(a + a, b / 2);
}
}
|
| 12
Ein Java-Programm
package demos;
public class Mult {
public static void main(String[] args) {
int i = 5, j = 9;
System.out.println(i + " * " + j + " = " + f(i,j));
}
static int f(int a, int b){ main übernimmt immer
if (b == 1)
dieses Argument
return a;
if (b % 2 == 0)
return f(a + a, b / 2);
else
return a + f(a + a, b / 2);
}
}
|
| 13
Primitive Datentypen
●
●
Werden in der Speicherverwaltung anders
behandelt
Effizienz: Byte-Darstellung
ohne OOP-Overhead
●
Wrapper-Klassen
●
int: Integer, …
|
| 14
Java Speicherverwaltung
●
Einfacher als C++
●
Aber undurchsichtiger
●
Keine Pointer
●
Dafür Referenzen
●
Löschen (delete) übernimmt der GarbageCollector
●
Funktionsaufrufe: „Call by value using reference“
●
Ausnahme bei allem: Primitive Typen
|
| 15
Beispiel Speicherverwaltung
SomeType p1, p2;
p1 = new SomeType();
p1.property = 42;
p2 = p1;
System.out.println(p1==p2); // ?!?
p2 = new SomeType();
p2.property = 42;
System.out.println(p1==p2); // ?!?
p1 = null;
|
| 16
Beispiel Speicherverwaltung
SomeType p1, p2;
p1 = new SomeType();
p1.property = 42;
p2 = p1;
System.out.println(p1==p2); // true
p2 = new SomeType();
p2.property = 42;
System.out.println(p1==p2); // false
p1 = null;
|
| 17
Parameterübergabe in Java
●
Call-by-Value
●
●
●
Daten werden kopiert
Keine Verbindung zwischen Daten des Aufrufers und der
Funktion
Call-by-Reference
●
●
Referenzen (Pointer) auf Daten werden übergeben
Änderungen innerhalb der Funktion sind von aussen
sichtbar
|
| 18
Parameterübergabe in Java
●
●
Java benutzt immer Call-by-Value
●
Bei primitiven Typen wird der Wert kopiert
●
Bei Referenztypen wird die Referenz kopiert
Wir können den Wert eines Parameters ändern, nicht aber
den Ort, wo er hinzeigt
|
| 19
Parameterübergabe in Java
public void move(Point p) {
p.x1 += 1;
p.y1 += 2;
}
Hauptprogramm ruft auf:
move(myPoint)
main(...)
myPoint
int x1; 5
int y1; 5
myPoint
p
int x1; 6
int y1; 7
Nach swap(...)
myPoint
int x1; 6
int y1; 7
p
|
| 20
Parameterübergabe in Java
public void swap(Point p1, Point p1) {
Point temp = p1;
p1 = p2;
p2 = temp;
}
Hauptprogramm ruft auf:
swap(myPoint1, myPoint2)
main(...)
myPoint1
myPoint2
myPoint1
int x1;
int y1;
Nach swap(...)
myPoint1
int x1;
int y1;
p1
p1
int x2;
int y2;
myPoint2
myPoint2
p2
int x2;
int y2;
int x1;
int y1;
int x2;
int y2;
p2
|
| 21
Array ↔ ArrayList
●
Array wie in C/C++
int x[] = new int[5];
for(int i = 0; i < 5; i++)
x[i] = i;
●
ArrayList<>: Entspricht C++ vector<>
●
Wächst automatisch
●
Java: Keine Operatorüberladung → keine []
●
set() auf falschen Index → IndexOutOfBoundsException
ArrayList<Integer> x = new ArrayList<Integer>();
for(int i = 0; i < 5; i++)
x.add(i, i);
●
Indizes beginnen bei 0!
|
| 22
Bytecode
●
C++ wird in (maschinenabhängigen) Assembler übersetzt
●
Java wird in maschinenunabhängigen Bytecode übersetzt
●
Dieser wird dann interpretiert
●
Kompilieren und Bytecode ansehen
●
Eclipse: .class-File reinziehen
●
Terminal
●
javac JavaTip.java //compiler
●
java JavaTip //run
●
javap –c –private JavaTip //disassembler
|
| 23
Bytecode Mnemonics
●
●
●
Gute Liste:
http://en.wikipedia.org/wiki/Java_bytecode_instruction_listi
ngs
Verkürzte Liste auf der PVK-Website
Was müsst ihr können?
●
(einfache) Bytecode-Programme interpretieren
●
Nach Java zurückübersetzen
●
NICHT selber Bytecode schreiben
●
Sicher nicht die ganze Liste auswendig können (Wir sind
keine Juristen)
|
| 24
Aufwand und Komplexität
|
| 25
Komplexität ↔ Aufwand
●
Gegebene Problemgrösse (oft # Eingabeelemente) n
●
Aufwand
●
●
Wie schnell ist ein bestimmter Algorithmus:
●
Günstigster Aufwand („best case“)
●
Mittlerer Aufwand („average case“)
●
Ungünstigster Aufwand („worst case“)
Komplexität des Problems
●
Eigenschaft des Problems, nicht des Algorithmus
●
Aufwand des bestmöglichen Algorithmus
|
| 26
Asymptotische Laufzeit und O-Notation
●
Bsp einer Laufzeit: 3*n2 + 5*n + 4*log(n)
●
Die exakte Laufzeit ist nicht so interessant
●
Für grosse n nur der n2-Term entscheidend
●
●
Die '3' ist auch recht egal, ich kann ja einen schnelleren PC
kaufen
Deshalb: Asymptotische Laufzeit O(n2)
●
●
„f wächst nicht wesentlich schneller als n2“
f ( n)
Math. korrekt: lim 2 <∞
n→∞ n
|
| 27
Laufzeiten von Schleifen
●
Schleifen nacheinander: Addition
for(int i=0; i<2*n; i++) a++;
for(int j=0; j<n; j++) a++;
Addition: 2*n+n=3*n → O(n)
●
Verschachtelte Schleifen: Multiplikation
for(int i=0; i<n; i++)
for(int j=0; j<n; j++) a++;
Multiplikation: n*n=n² → O(n²)
|
| 28
Prüfungsrelevanz
●
Komplexität eines Codes angeben
●
●
Verschachtelte Schleifen
Code auf gewünschte Laufzeit ergänzen
|
| 29
Objektorientierung
|
| 30
Visibility
●
private
●
●
protected
●
●
Für Kindsklassen und Klassen des selben Pakets
sichtbar
public
●
●
Nur innerhalb der Klasse sichtbar
Für alle sichtbar
Kapselung: Implementierung ist privat, Schnittstelle
öffentlich
|
| 31
Vererbung
●
Möglich:
●
Ergänzen der Klasse (extends)
●
Ändern von public / protected Funktionen
●
Überschreiben von private-Funktionen
●
Nicht möglich:
●
Dinge entfernen
●
Von mehreren Klassen erben
●
Aber: Mehrere Interfaces implementieren ist möglich
|
| 32
Final
●
Bisher: final (Java) ↔ const (C++)
●
Neu: finale Methoden & Klassen
●
Eine final-Methode kann nicht überschrieben werden
●
Von einer final Klasse kann nicht vererbt werden
●
z. B. Integer, Character, ...
|
| 33
Abstrakte Klassen
●
●
Eine Klasse kann Methoden deklarieren, diese aber nicht
implementieren
Abgeleitete Klassen müssen diese implementieren
●
●
Ausser sie sind selbst auch abstrakt
Deklaration:
public abstract class MyClass {
public abstract void function();
}
●
Object ist Basisklasse von allen anderen Klassen
|
| 34
Interfaces
●
Implementieren keine Methoden
●
Dienen zur Definition der Schnittstelle einer Klasse
●
„Vertrag“
●
Methoden sind public abstract
●
Eine Klasse kann mehrere Interfaces implementieren
●
●
implements
Ein Smartphone ist eine Implementation von Telefon und
Computer
|
| 35
Beispiel Interface ↔ Abstrakte Klasse
public interface IStack {
int size();
void push(Object obj);
Object pop();
Object peek();
boolean empty();
}
public class MyStack implements IStack {
private int size;
public int size() {
return size;
}
public void push(Object obj) {
...
}
...
}
|
| 36
Beispiel Interface ↔ Abstrakte Klasse
public abstract class BaseStack implements IStack {
public abstract int size();
public abstract void push(Object obj);
public abstract Object pop();
public Object peek()
{ Object top = pop(); push(top); return top; }
public boolean empty() { return size() == 0; }
}
public class MyStack extends BaseStack {
private GenericList first;
public Object peek() {
return first.value;
}
...
}
|
| 37
Static und Dynamic Casting
Casten ist „von unten nach oben“ möglich
static cast
●
Aa= b
●
●
Muss zur Kompilierzeit überprüfbar sein, sonst Fehler
dynamic cast
●
A a = (A) b
●
●
Darf zur Compilezeit unbestimmt sein
Muss zur Laufzeit korrekt sein, sonst
ClassCastException
|
| 38
Static und dynamic casts
Person
Student
Employee
Person p = new Person(...);
Student s = new Student(...);
Employee e = new Employee(...);
Person ps = s Student sps = ps Person pe = e
Student dsps = (Student) ps
Student sp = p Employee deps = (Employee) ps
|
21.06.15
| 39
Static und dynamic casts
Person
Student
Employee
Person p = new Person(...);
Student s = new Student(...);
Employee e = new Employee(...);
Person ps = s ­> ok
Person pe = e
­> ok
Student sp = p ­> compile error
Student sps = ps ­> compile error
Student dsps = (Student) ps
­> ok
Employee deps = (Employee) ps
­> runtime error
|
21.06.15
| 40
instanceof
Person
Student
Employee
Person p = new Person(...);
Student s = new Student(...);
Employee e = new Employee(...);
p instanceof Person
true
p instanceof Student false
s instanceof Person true
s instanceof Student true
|
21.06.15
| 41
Generics
●
●
●
Klasse auf beliebigen Typ implementieren
Wiederverwertung von Code
Generic-Typ kann wie eine normale Klasse verwendet
werden
public class MyClass<T extends BaseClass> {
public abstract T function();
}
|
| 42
Das war der Theorieteil :)
|
| 43
Syntaxanalyse & -bäume
|
| 44
Grundlagen der Syntaxanalyse
●
Beispiel arithmetische Ausdrücke
3*(6-2)+(4-2+5)*7
●
●
●
Lässt sich nur sehr mühsam Zeichen für Zeichen
analysieren
Die Multiplikation an Position 1 kann nicht sofort
ausgeführt werden, da zuerst die Klammer ausgewertet
werden muss.
Idee: Rekursive Lösung
|
| 45
Bsp. arithmetische Ausdrücke (Skript S. 148 ff)
●
Elemente
●
Verzweigung: Beides möglich
●
Kreis: bestimmtes Zeichen
●
●
●
Rechteck: Aufruf an anderes
Element
Starte bei „Ausdruck“
Bei Misserfolg versuche
einfach das nächst-mögliche
|
| 46
Bsp. arithmetische Ausdrücke (Skript S. 148 ff)
void int_const() throws... {
if(c < '0' || c > '9') {
throw new InvalidIntException();
}
readchar();
}
void Ausdruck() throws... {
Term();
while(c == '+') {
readchar();
Term();
Es kann beliebig viele Terme
}
geben. Aber so lange noch ein
}
Plus kommt, muss auch ein
Term kommen.
|
| 47
Bsp. arithmetische Ausdrücke (Skript S. 148 ff)
void Term() throws... {
Faktor();
while(c == '*') {
readchar();
Faktor();
}
}
void Faktor() throws... {
if(c == '(') {
readchar();
Ausdruck();
if(c != ')')
throw new BracketException();
} else
int_const();
}
|
| 48
Pre-, In- und Post Order
●
Pre Order: Gib zuerst das aktuelle Element aus, dann die
Kinder
●
●
In Order: Linkes Kind, aktuelles Element, rechtes Kind
●
●
Infix: 3 + 4
Post Order: Aktuelles Element, dann beide Kinder
●
●
„Polish“ / prefix: + 3 4
„Reverse polish“ / postfix: 3 4 +
Folge der Stadtmauer
|
| 49
Prüfungsrelevanz
●
Anhand von Diagrammen Gültigkeit entscheiden
●
Im Normalfall Sachen, die nicht komplett offensichtlich
sind, so dass nach Diagrammen gegangen werden muss.
●
Code für eine Funktion einfügen
●
Pre-, In- & Post-Order Ausgabe von Syntaxbäumen
|
| 50
Verkettete Listen
|
| 51
Idee der verketteten Liste
●
Bisher kennen wir Arrays und ArrayList
●
●
●
ArrayList hat den Vorteil, dass Java Vergrösserungen
automatisch übernimmt. Man muss nicht mehr Platz
allozieren
Beide sind aber mühsam, wenn mehr Platz braucht:
Alle alten Werte müssen kopiert werden.
Idee der LinkedList:
●
Die Werte müssen nicht in einem Block gespeichert sein
●
Ein Element speichert zusätzlich den Ort des nächsten
|
| 52
Idee der verketteten Liste
●
Ein Element ist ein Tupel aus
●
Wert (beliebiger Datentyp)
●
Referenz auf das nächste (C++: Pointer)
myList
value
76
value
15
value
22
value
3
value
32
next
next
next
next
next
|
| 53
Operationen auf verketteter Liste (Serie 5)
ReadOnly
Modifizierend
●
add
●
append
●
size
●
concat
●
sum
●
insertAt
●
last
●
remove
●
sublist
●
valueAt
●
index
|
| 54
Rekursive Implementierung
●
Idee ist immer gleich:
●
●
●
Abbruchbedingung prüfen
Falls nicht erreicht, „irgendwie“ an den Nachfolger
übergeben
Hier am Beispiel von index(List list, int value)
public static int index(List list, int value) throws NoSuchElementException {
if(list == null) throw new NoSuchElementException();
if(list.value == value) return 0;
return 1 + index(list.next, value);
}
|
| 55
Insertion Sort
●
●
Sehr einfaches Sortierverfahren
●
Gut geeignet für verkettete Listen
●
O(n2) (recht schlecht)
Idee
●
Ein Element in eine sortierte Liste einfügen ist einfach
●
Vor dem ersten grösseren einfügen (aufsteigend)
●
Füge einfach alle Elemente in eine wachsende Liste ein
●
Leere Liste ist sortiert
|
| 56
Insertion Sort
●
InsertSorted
public static List insertSorted(List list, int value) {
if (list == null) return new List(value, null);
if (value < list.value) return new List(value, list);
list.next = insertSorted(list.next, value);
return list;
}
●
sort
public static List sort(List list) {
if (list == null) return null;
return insertSorted(sort(list.next), list.value);
}
|
| 57
Prüfungsrelevanz
●
Die rekursiven Operationen auf verketteten Listen kennen
●
Funktionen ausfüllen können
●
Mindestens in Pseudocode
|
| 58
Stacks
|
| 59
Grundlagen Stacks
●
Stack = Stapel
●
Menge Elemente in einer Liste
●
●
Nur das oberste zugänglich
●
LIFO (Last in first out)
Schnittstelle unabhängig von Container
●
Ihr habt (mind.) 2 implementiert:
●
ArrayList
●
LinkedList
|
| 60
Operationen Stack
●
●
Minimale Schnittstelle:
●
push: Neues Element auf Stack legen
●
pop: Oberstes Element entfernen und zurückgeben
●
peek: Oberstes Element anschauen aber drin lassen
Weitere Operationen
●
size
●
empty
●
toString
|
| 61
Prüfungsrelevanz
●
Operationen kennen und implementieren können
|
| 62
Herunterladen