FB Automatisierung und Informatik: Programmierung 1, MI/WI 1
Programmierung 1 Studiengang MI / WI
Dipl.-Inf., Dipl.-Ing. (FH) Michael Wilhelm
Hochschule Harz
FB Automatisierung und Informatik
mwilhelm@hs-harz.de
http://mwilhelm.hs-harz.de
Raum 2.202
Tel. 03943 / 659 338
Inhalt der Vorlesung
Überblick:
• Erste Beispiele, Interaktion
• elementare Datentypen
• Variablen und Kontrollstrukturen
• Arrays und Funktionen
• Objekte und Methoden
• Algorithmen und Pseudocode
• Laufzeitverhalten
• Simulation
• Bibliotheken
• Template und generische Klassen
Grundlegende Algorithmen und Methoden:
• Suchen und Sortieren
• Hashing
• Rekursion
• Graphen
• Dynamische Programmierung
Von Processing zu Java
FB Automatisierung und Informatik: Programmierung 1, MI/WI 33
Kapitel
Schnelles Suchen (Hashing)
•
Hash-Funktion
•
Hash-Map
•
Hash-Set
Hashing / HashTable / HashMap / HashSet
Definition Hashing:
•
Die Objekte werden in einem Feld mit Indizies 0 bis N-1 gespeichert.
•
Die einzelnen Speicherpositionen werden Buckets genannt.
•
Eine Hashfunktion h : e --> N bestimmt für ein
Schlüsselelement e einen Bucket h(e) im Feld, in dem ein mit dem Schlüssel e assoziertes Element gespeichert werden soll.
•
Die Wahl der Funktion h hat entscheidenden Einfluss auf die Qualität des Verfahrens.
Kollision:
•
Eine Kollision tritt auf, wenn für e1 ≠ e2 gilt h(e1) = h(e2)
FB Automatisierung und Informatik: Programmierung 1, MI/WI 5
Beispiel:
Wir wählen die ganzen Zahlen als Element e. Ein Feld der Größe N. Die Hashfunktion sei h(e) = e mod N. Gespeichert werden sollen 42 und 119. Hier ist N = 10.
Problem:
•
Es soll noch der Wert 69 gespeichert werden. Jedoch ist 69 mod 10 = 9. Dieser Bucket ist bereits belegt. Wie soll bei einer Kollision verfahren werden?
Beachte:
•
Man kann zeigen: Idealerweise ist die Größe der Hashtabelle eine Primzahl, die aber nicht nahe bei einer Zweierpotenz liegen sollte.
Index 0 1 2 3 4 5 6 7 8 9
Eintrag 42 119
Hashfunktionen
•
Hashfunktionen sollen “gute” Eigenschaften besitzen.
•
Insbesondere sollen sie die zur Verfügung stehenden Buckets möglichst gleichmäßig füllen.
•
Sie sollen aber auch einfach berechenbar sein, denn die Kosten ein Element zu speichern sind direkt proportional zu den Kosten der Berechnung der Hashfunktion.
•
Der Zugriff auf Elemente einer Hashtabelle ist O(1).
FB Automatisierung und Informatik: Programmierung 1, MI/WI 7
Hashfunktionen
Umgang mit Kollisionen:
•
Verkettung:
•
Alle kollidierenden Elemente werden im selben Bucket gespeichert, etwa in einer ArrayList.
•
Sondieren: suche einen freien Bucket
•
lineares Sondieren
•
quadratisches Sondieren
Doppelte Hashwerte in einer Liste speichern
•
Ein Überläufer ist ein Element, welches eine bereits gefüllte Position in der Hashtabelle zum Überlaufen bringt. Bei der Verkettung der Überläufer werden diese für jeden Bucket in einem Array [oder einer verketteten Liste (siehe 2. Semester)]
untergebracht.
•
Bei vielen Überläufern kann die Tabelle entarten, d.h. viele Elemente befinden sich in einem gemeinsamen Bucket, mit Zugriffszeiten von O(N).
Index 0 1 2 3 4 5 6 7 8 9
Eintrag
FB Automatisierung und Informatik: Programmierung 1, MI/WI 9
Lineares Sondieren
•
Bei einer Kollision für T[h(e]] werden der Reihe nach die Buckets überprüft
•
T[h(e) + 1]; T[h(e) + 2], ...
•
Das Element wird im ersten so gefundenen freien Bucket abgespeichert.
•
Hierbei bezeichnet T[x] den zu x mod N gehörigen Bucket.
Index 0 1 2 3 4 5 6 7 8 9
Eintrag 69 29 42 119
Quadratisches Sondieren
•
lineares Sondieren führt oft zu einer Konzentration der Elemente in der Nähe weniger Buckets.
•
Quadratisches Sondieren verhindert dies.
•
T[h(e) + 1]; T[h(e) + 4]; T[h(e) + 9]; ....
Index 0 1 2 3 4 5 6 7 8 9
Eintrag 69 42 29 119
FB Automatisierung und Informatik: Programmierung 1, MI/WI 11
Re-Hashing
•
Wird keine Verkettung der Überläufer durchgeführt, so muss die Hashtabelle groß genug sein um alle zu speichernden Elemente aufnehmen zu können.
•
Sollte dies nicht der Fall sein, muss sie entsprechend vergrößert werden.
•
Dann muss für jeden Eintrag ein neuer Bucket, entsprechend der neu berechneten Hashfunktion, bestimmt werden.
Hashfunktion und equals
•
Beachte: Falls die Hashfunktion für zwei Objekte
denselben Wert ergibt, folgt hieraus nicht, dass die beiden Objekte gleich sind.
•
Aber da zwei gleiche Objekte denselben Hashwert haben müssen, heißt dies auch:
•
Falls der Hashwert zweier Objekte nicht gleich ist, können auch die Objekte nicht gleich sein.
•
In mathematischer Notation für die Objekte A und B sowie ihre Hashwerte h
Aund h
B:
A = B ⇒ h
A= h
B⇔ hA ≠ hB ⇒ A ≠ B
FB Automatisierung und Informatik: Programmierung 1, MI/WI 13
hashcode und equals
•
Falls Objekte in Hashtabellen (oder allgemeiner in Collections) gespeichert werden sollen, muss immer eine entsprechende equals-Methode
implementiert sein. Diese muss immer konsistent mit der hashCode-Methode sein.
•
Also, falls Sie equals implementieren, dann sollten Sie auch hashCode implementieren und umgekehrt
•
Eclipse kann equals und hashCode für eine Klasse automatisch erzeugen.
Menü Source
FB Automatisierung und Informatik: Programmierung 1, MI/WI 15
@Override
public int hashCode() { final int prime = 31;
int result = 1;
if (firma == null) result=prime*result+
firma.hashCode();
else result = 0;
result = prime * result + kw;
return result;
}
@Override
public boolean equals(Object obj) { if (this == obj)
return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
Auto other = (Auto) obj;
if (firma == null) { if (other.firma != null) return false;
} else if (!firma.equals(other.firma)) return false;
if (kw != other.kw) return false;
return true;
}
HashMap in Java
•
HashMap in Java: Schlüssel (hier String) und Wert (hier Klasse) getrennt.
HashMap<String, Klasse> hash;
hash = new HashMap<String, Klasse>();
hash.put("variable", new Klasse());
Klasse k = hash.get("variable");
• typische Anwendung:
• Datenbanken
• mögliche Schlüssel:
• Name, Steuernummer, ...
FB Automatisierung und Informatik: Programmierung 1, MI/WI 17
HashSet in Java (verwaltet eine Menge)
•
HashSet in Java: Schlüssel (via hashCode) und Wert gemeinsam in Klasse.
HashSet<Klasse> hash = new HashSet<Klasse>();
Klasse k = new Klasse();
hash.add(k);
boolean found = hash.contains(k);
•
HashSet hat Eigenschaften einer Menge, d.h. kein Element kann mehrfach auftreten (equals).
•
Dies muss gegebenenfalls vor dem Einfügen überprüft werden.
Zusammenfassung
•
Interfaces erlauben Verträge über zu implementierende Methoden in Klassen abzuschliessen.
•
Generische Klassen dienen der typsicheren Programmierung.
Der Compiler entfernt beim Übersetzen diese Information.
•
ArrayList<T> implementiert dynamisch wachsende Arrays.
•
Hashing berechnet den Index in einem Array an dem Information abgelegt werden soll.
•
Hash-Indizes sind nicht eindeutig -- es können Kollisionen auftreten.
•
Kollision werden mit Verkettung oder (linearem, quadratischem) Sondieren behandelt.
•