Wörterbuch (Dictionary)

Ähnliche Dokumente
C++-Zusammenfassung. H. Schaudt. August 18, 2005

(27 - Selbstanordnende lineare Listen)

Vorlesung Datenstrukturen

Objektorientierte Programmierung

Es sei a 2 und b 2a 1. Definition Ein (a, b)-baum ist ein Baum mit folgenden Eigenschaften:

Termine für Übungstests. Kap. 3 Sortieren HeapSort ff Priority Queues. Motivation. Überblick. Analyse SiftDown

Objektorientierte Programmierung mit C++ Vector und List

Advanced Programming in C

Methoden. von Objekten definiert werden, Methoden,, Zugriffsmethoden und Read-Only

Der linke Teilbaum von v enthält nur Schlüssel < key(v) und der rechte Teilbaum enthält nur Schlüssel > key(v)

10. Klassen. Prof. Dr. Markus Gross Informatik I für D-ITET (WS 03/04)

Grundlagen der Programmierung Prof. H. Mössenböck. 6. Methoden

13. Binäre Suchbäume

Informatik II, SS 2014

Systemnahe Programmierung in C/C++

Klausur C-Programmierung / / Klingebiel / 60 Minuten / 60 Punkte

Vorkurs C++ Programmierung

Programmieren - C++ Funktions-Templates

Name: Seite 2. Beantworten Sie die Fragen in den Aufgaben 1 und 2 mit einer kurzen, prägnanten Antwort.

Besonderheiten von C#

AVL-Bäume Analyse. Theorem Ein AVL-Baum der Höhe h besitzt zwischen F h und 2 h 1 viele Knoten. Definition Wir definieren die nte Fibonaccizahl:

Programmierkurs. SoSe Markus Geveler Inst. f. Applied Mathematics, TU Dortmund.

Praxisorientierte Einführung in C++ Lektion: "Smart-Pointer"

Programmieren in C++ Überladen von Methoden und Operatoren

Probeklausur: Programmierung WS04/05

JAVA KURS COLLECTION

Kapitel 9 Suchalgorithmen

In der Computersprache C ist die Standardmethode zur Behandlung von Matrizen durch

Algorithmen und Datenstrukturen Wintersemester 2004/ November T(n) = T(n a) + T(a) + n

Kapitel 4: Dynamische Datenstrukturen. Algorithmen und Datenstrukturen WS 2012/13. Prof. Dr. Sándor Fekete

Suchen und Sortieren Sortieren. Heaps

Lösungsvorschläge. zu den Aufgaben im Kapitel 4

Methoden (fortgeschritten) in C# - 1

Programmiertechnik II

Binäre Bäume. 1. Allgemeines. 2. Funktionsweise. 2.1 Eintragen

Abschnitt: Algorithmendesign und Laufzeitanalyse

Algorithmen und Datenstrukturen

1. Musterlösung. Problem 1: Average-case-Laufzeit vs. Worst-case-Laufzeit

Probeklausur: Programmierung WS04/05

Von der UML nach C++

Grundlagen der Informatik. Prof. Dr. Stefan Enderle NTA Isny

3. Übung Algorithmen I

DAP2-Programmierpraktikum Einführung in C++ (Teil 1)

3 Klassen, Attribute, Methoden

Einführung in die STL

Übungen zur Vorlesung EidP (WS 2015/16) Blatt 6

2. Methoden. n Generelles zum Aufruf von Methoden. n Parameterübergabemechanismen (call by value, call by reference)

Übersicht Datenstrukturen und Algorithmen. Literatur. Algorithmus: Wikipedia Definition. Vorlesung 1: Einführung. Prof. Dr.

Java Einführung Collections

Einführung in die Programmierung

Algorithmen und Datenstrukturen

Einführung Datentypen Verzweigung Schleifen. Java Crashkurs. Kim-Manuel Klein May 4, 2015

THE GO PROGRAMMING LANGUAGE. Michael Karnutsch & Marko Sulejic

C++ - Operatoren. Eigene Klassen mit neuen Funktionen

Überladen von Operatoren

Kap. 4.4: B-Bäume Kap. 4.5: Dictionaries in der Praxis

Algorithmen und Datenstrukturen 1-1. Seminar -

Einstieg in die Informatik mit Java

Übersicht. Datenstrukturen und Algorithmen Vorlesung 5: Rekursionsgleichungen (K4) Übersicht. Binäre Suche. Joost-Pieter Katoen. 20.

Binäre Suchbäume. Mengen, Funktionalität, Binäre Suchbäume, Heaps, Treaps

Es ist für die Lösung der Programmieraufgabe nicht nötig, den mathematischen Hintergrund zu verstehen, es kann aber beim Verständnis helfen.

Studentische Lösung zum Übungsblatt Nr. 7

Einführung Elementare Datenstrukturen. Der Konstruktor muß den Listenkopf head erzeugen. Der Vorgänger und Nachfolger von head ist head selbst.

Übung zur Vorlesung Algorithmische Geometrie

4.4.1 Statisches perfektes Hashing. des Bildbereichs {0, 1,..., n 1} der Hashfunktionen und S U, S = m n, eine Menge von Schlüsseln.

Algorithmen & Datenstrukturen 1. Klausur

EndTermTest PROGALGO WS1516 A

In diesem Kapitel behandeln wir erste Algorithmen mit dynamischen Strukturen, wie Bäume und Graphen. 1. Bäume Grundlagen...

Java Einführung Methoden in Klassen

Einführung in den Einsatz von Objekt-Orientierung mit C++ I

Komplexität von Algorithmen

Einführung Datentypen Verzweigung Schleifen Funktionen Dynamische Datenstrukturen. Java Crashkurs. Kim-Manuel Klein

Teil 1: Suchen. Problemstellung Elementare Suchverfahren Hashverfahren Binäre Suchbäume Ausgeglichene Bäume. B-Bäume Digitale Suchbäume Heaps

Kapitel 9. Komplexität von Algorithmen und Sortieralgorithmen

6 Speicherorganisation

Wiederholung ADT Menge Ziel: Verwaltung (Finden, Einfügen, Entfernen) einer Menge von Elementen

Theorie zu Übung 8 Implementierung in Java

Bäume. Text. Prof. Dr. Margarita Esponda SS 2012 O4 O5 O6 O ALP2-Vorlesung, M. Esponda

UNIVERSITÄT ULM Fakultät für Ingenieurswissenschaften und Informatik Institut für Datenbanken und Informationssysteme

Algorithmen zur Datenanalyse in C++

Kapitel 9. Komplexität von Algorithmen und Sortieralgorithmen

Kontrollstrukturen und Funktionen in C

Java 8. Elmar Fuchs Grundlagen Programmierung. 1. Ausgabe, Oktober 2014 JAV8

Bereits behandelt: Einfache Datentypen / Variablen. Schleifen und Verzweigungen. Funktionen. Heute: Felder, Zeiger, Referenzen. Freispeicherverwaltung

11. Übung Informatik II - Operatorfunktionen

0. Einführung & Motivation

Java Einführung Methoden. Kapitel 6

Kapitel : Andere dynamische Datenstrukturen. Algorithmen und Datenstrukturen WS 2013/14. Prof. Dr. Sándor Fekete

Programmieren in C++ Arrays, Strings und Zeigerarithmetik

Praktikum Betriebssysteme 1. Aufgabe (1)

Dynamische Speicherverwaltung

Kapitel 2: Analyse der Laufzeit von Algorithmen Gliederung

EINI WiMa/LW. Einführung in die Informatik für Naturwissenschaftler und Ingenieure. Vorlesung 2 SWS WS 11/12

Programmieren von Webinformationssystemen

Java I Vorlesung 6 Referenz-Datentypen

Ich liebe Java && Ich liebe C# Rolf Borst

Datenstrukturen und Algorithmen

Überblick. Lineares Suchen

1. Grundzüge der Objektorientierung 2. Methoden, Unterprogramme und Parameter 3. Datenabstraktion 4. Konstruktoren 5. Vordefinierte Klassen

Deklarationen in C. Prof. Dr. Margarita Esponda

Transkript:

Wörterbuch (Dictionary) 12. Wörterbücher Wörterbuch, Selbstandornung, Implementation Wörterbuch mit Array / Liste / Sipliste. [Ottman/Widmayer, Kap. 3.3,1.7, Cormen et al, Kap. Problem 17-5] ADT zur Verwaltung von Schlüsseln aus K mit Operationen insert(, D): Hinzufügen von K in Wörterbuch D. Bereits vorhanden Fehlermeldung. delete(, D): Löschen von aus dem Wörterbuch D. Nicht vorhanden Fehlermeldung. search(, D): Liefert true wenn D, sonst false. 312 313 Idee Andere Idee Implementiere Wörterbuch als sortiertes Array. Anzahl Elementaroperationen im schlechtesten Fall Suchen O(log n) Einfügen O(n) Löschen O(n) Implementiere Wörterbuch als verettete Liste Anzahl Elementaroperationen im schlechtesten Fall Suchen O(n) Einfügen O(1) 13 Löschen O(n) 314 13 Unter der Voraussetzung, dass wir die Existenz nicht prüfen wollen. 315

Selbstanordnung Transpose Problematisch bei der Verwendung veretteter Listen: lineare Suchzeit Idee: Versuche, die Listenelemente so anzuordnen, dass Zugriffe über die Zeit hinweg schneller möglich sind Zum Beispiel Transpose: Bei jedem Zugriff auf einen Schlüssel wird dieser um eine Position nach vorne bewegt. Move-to-Front (MTF): Bei jedem Zugriff auf einen Schlüssel wird dieser ganz nach vorne bewegt. Transpose: n 1 n n 1 n 1 2 3 4 5 n 1 n Worst case: n Wechselnde Zugriffe auf n 1 und n. Laufzeit: Θ(n 2 ) 316 317 Move-to-Front Analyse Move-to-Front: n 1 n1 n 1 12 21 3 23 4 45 3 n 1 n 2 n 3 n 2 n n Wechselnde Zugriffe auf n 1 und n. Laufzeit: Θ(n) Man ann auch hier Folge mit quadratischer Laufzeit angeben, z.b. immer das letzte Element. Aber dafür ist eine offensichtliche Strategie beannt, die viel besser sein önnte als MTF. Vergleichen MTF mit dem bestmöglichen Konurrenten (Algorithmus) A. Wie viel besser ann A sein? Annahme: MTF und A dürfen jeweils nur das zugegriffene Element x verschieben. MTF und A starten mit derselben Liste. M und A bezeichnen die Liste nach dem -ten Schritt. M 0 = A 0. 318 319

Analyse Kosten: Zugriff auf x: Position p von x in der Liste. Keine weiteren Kosten, wenn x vor p verschoben wird. Weitere Kosten q für jedes Element, das x von p aus nach hinten verschoben wird. p x q Amortisierte Analyse Sei eine beliebige Folge von Suchanfragen gegeben und seien G (M) und G (A) jeweils die Kosten im Schritt für Move-to-Front und A. Suchen Abschätzung für G(M) im Vergleich zu G(A). Amortisierte Analyse mit Potentialfuntion Φ. 320 321 Potentialfuntion Potentialfuntion Φ = Anzahl der Inversionen von A gegen MTF. Inversion = Paar x, y so dass für die Positionen von x und y p (A) (x) < p (A) (y) p (M) (x) > p (M) (x) oder p (A) (x) > p (A) (y) p (M) (x) < p (M) (x) A 1 2 3 4 5 6 7 8 9 10 M 4 1 2 10 6 5 3 7 8 9 #Inversionen = #Kreuzungen Abschätzung der Potentialfuntion: MTF Element i an Position p i := p (M) (i). Zugriffsosten C (M) = p i. x i : Anzahl Elemente, die in M vor p i und in A nach i stehen. MTF löst x i Inversionen auf. p i x i 1: Anzahl Elemente, die in M vor p i und in A vor i stehen. MTF erzeugt p i 1 x i Inversionen. A 1 2 3 4 5 6 7 8 9 10 M 4 1 2 10 6 5 3 7 8 9 A 1 2 3 4 5 6 7 8 9 10 M +1 5 4 1 2 10 6 3 7 8 9 322 323

Abschätzung der Potentialfuntion: A Abschätzung (obda) Element i an Position i. X (A) : Anzahl Verschiebungen nach hinten (sonst 0). Zugriffsosten für i: = i C (A) A erhöht die Anzahl Inversionen um X (A). A 1 2 3 4 5 6 7 8 9 10 M +1 5 4 1 2 10 6 3 7 8 9 A +1 1 2 3 4 6 7 5 8 9 10 M +1 5 4 1 2 6 3 10 7 8 9 Φ +1 Φ = x i + (p i 1 x i ) + X (A) Amortisierte Kosten von MTF im -ten Schritt: a (M) = C (M) + Φ +1 Φ p i x i + (p i 1 x i ) + X (A) = (p i x i ) + (p i x i ) 1 + X (A) C (A) + C (A) 1 + X (A). 324 325 Abschätzung Kosten Summiert G (M) = C (M) a (M) = 2 2 C (A) G (A) + X (A) 2 C (A) 1 + X (A) 2 C (A) + X (A) Coole Idee: Siplisten Perfete Sipliste 3 2 1 0 x 1 x 2 x 3 x 4 x 5 x 6 x 7 x 8 MTF führt im schlechtesten Fall höchstens doppelt so viele Operationen aus wie eine optimale Strategie. x 1 x 2 x 3 x 9. Beispiel: Suche nach einem Schlüssel x mit x 5 < x < x 6. 326 327

Analyse Perfete Sipliste (schlechtester Fall) Randomisierte Sipliste Idee: Füge jeweils einen Knoten mit zufälliger Höhe H ein, wobei P(H = i) = 1 2 i+1. Suchen in O(log n). Einfügen in O(n). 3 2 1 0 x 1 x 2 x 3 x 4 x 5 x 6 x 7 x 8 328 329 Analyse Randomisierte Sipliste Theorem Die Anzahl an erwarteten Elementaroperationen für Suchen, Einfügen und Löschen eines Elements in einer randomisierten Sipliste ist O(log n). 13. C++ vertieft (III): Funtoren und Lambda Der längliche Beweis, welcher im Rahmen dieser Vorlesung nicht geführt wird, betrachtet die Länge eines Weges von einem gesuchten Knoten zurüc zum Startpunt im höchsten Level. 330 331

Nachtrag zur Move-Semanti 13.1 Nachträge zum vorigen C++ Kapitel // nonsense implementation of a "vector" for demonstration purposes class vec{ public: vec () { std::cout << "default constructor\n"; vec (const vec&) { std::cout << "\n"; vec& operator = (const vec&) { std::cout << "copy assignment\n"; return this; ~vec() { ; 332 333 Wie viele Kopien? vec operator + (const vec& a, const vec& b){ vec tmp = a; // add b to tmp return tmp; int main (){ vec f; f = f + f + f + f; Ausgabe default constructor copy assignment 4 Kopien des Vetors Nachtrag zur Move-Semanti // nonsense implementation of a "vector" for demonstration purposes class vec{ public: vec () { std::cout << "default constructor\n"; vec (const vec&) { std::cout << "\n"; vec& operator = (const vec&) { std::cout << "copy assignment\n"; return this; ~vec() { // new: move constructor and assignment vec (vec&&) { std::cout << "move constructor\n"; vec& operator = (vec&&) { std::cout << "move assignment\n"; return this; ; 334 335

Wie viele Kopien? vec operator + (const vec& a, const vec& b){ vec tmp = a; // add b to tmp return tmp; int main (){ vec f; f = f + f + f + f; Ausgabe default constructor move assignment 3 Kopien des Vetors Wie viele Kopien? vec operator + (vec a, const vec& b){ // add b to a return a; int main (){ vec f; f = f + f + f + f; Ausgabe default constructor move constructor move constructor move constructor move assignment 1 Kopie des Vetors Erlärung: Move-Semanti ommt zum Einsatz, wenn ein x-wert (expired) zugewiesen wird. R-Wert-Rücgaben von Funtionen sind x-werte. 336 http://en.cppreference.com/w/cpp/language/value_category 337 Wie viele Kopien void swap(vec& a, vec& b){ vec tmp = a; a=b; b=tmp; int main (){ vec f; vec g; swap(f,g); Ausgabe default constructor default constructor copy assignment copy assignment 3 Kopien des Vetors X-Werte erzwingen void swap(vec& a, vec& b){ vec tmp = std::move(a); a=std::move(b); b=std::move(tmp); int main (){ vec f; vec g; swap(f,g); Ausgabe default constructor default constructor move constructor move assignment move assignment 0 Kopien des Vetors Erlärung: Mit std::move ann man einen L-Wert Ausdruc zu einem X-Wert (genauer: zu einer R-Wert Referenz) machen. Dann ommt wieder Move-Semanti zum Einsatz. http://en.cppreference.com/w/cpp/utility/move 338 339

Funtoren: Motivierung 13.2 Funtoren und Lambda-Expressions Ein simpler Ausgabefilter template <typename T, typename function> void filter(const T& collection, function f){ for (const auto& x: collection) if (f(x)) std::cout << x << " "; std::cout << "\n"; 340 341 Funtoren: Motivierung template <typename T, typename function> void filter(const T& collection, function f); template <typename T> bool even(t x){ return x % 2 == 0; std::vector<int> a {1,2,3,4,5,6,7,9,11,16,19; filter(a,even<int>); // output: 2,4,6,16 Funtor: Objet mit überladenem Operator () class LargerThan{ int value; // state public: LargerThan(int x):value{x{; bool operator() (int par){ return par > value; ; std::vector<int> a {1,2,3,4,5,6,7,9,11,16,19; int value=8; filter(a,largerthan(value)); // 9,11,16,19 Funtor ist ein aufrufbares Objet. Kann verstanden werden als Funtion mit Zustand. 342 343

Funtor: Objet mit überladenem Operator () template <typename T> class LargerThan{ T value; public: LargerThan(T x):value{x{; ; bool operator() (T par){ return par > value; (geht natürlich auch mit Template) Dasselbe mit Lambda-Expression std::vector<int> a {1,2,3,4,5,6,7,9,11,16,19; int value=8; filter(a, [value](int x) {return x>value; ); std::vector<int> a {1,2,3,4,5,6,7,9,11,16,19; int value=8; filter(a,largerthan<int>(value)); // 9,11,16,19 344 345 Summe aller Elemente - lassisch std::vector<int> a {1,2,3,4,5,6,7,9,11,16,19; int sum = 0; for (auto x: a) sum += x; std::cout << sum << "\n"; // 83 Summe aller Elemente - mit Funtor template <typename T> struct Sum{ T & value = 0; Sum (T& v): value{v { ; void operator() (T par){ value += par; 346 std::vector<int> a {1,2,3,4,5,6,7,9,11,16,19; int s=0; Sum<int> sum(s); sum = std::for_each(a.begin(), a.end(), sum); std::cout << s << "\n"; // 83 347

Summe aller Elemente - mit Λ std::vector<int> a {1,2,3,4,5,6,7,9,11,16,19; int s=0; std::for_each(a.begin(), a.end(), [&s] (int x) {s += x; ); std::cout << s << "\n"; Sortieren, mal anders // pre: i >= 0 // post: returns sum of digits of i int q(int i){ int res =0; for(;i>0;i/=10) res += i % 10; return res; std::vector<int> v {10,12,9,7,28,22,14; std::sort (v.begin(), v.end(), [] (int i, int j) { return q(i) < q(j); ); 348 Jetzt v =10, 12, 22, 14, 7, 9, 28 (sortiert nach Quersumme) 349 Lambda-Expressions im Detail Closure [value] (int x) ->bool {return x>value; [value] (int x) Capture Parameter Rücgabetyp ->bool {return x>value; Anweisung Lambda-Expressions evaluieren zu einem temporären Objet einer closure Die closure erhält den Ausführungsontext der Funtion, also die captured Objete. Lambda-Expressions önnen als Funtoren implementiert sein. 350 351

Simple Lambda-Expression Minimale Lambda-Expression []{ []() >void {std::cout << "Hello World"; Aufruf: []() >void {std::cout << "Hello World";(); Rücgabetyp ann inferiert werden, wenn ein oder nur ein return: []() {std::cout << "Hello World"; Wenn eine Parameter und eine Rücgabe, ann () weggelassen werden []{std::cout << "Hello World"; [...] ann nie weggelassen werden. 352 353 Beispiele Beispiele [](int x, int y) {std::cout << x y; (4,5); Output: 20 int = 8; [](int& v) {v += v; (); std::cout << ; Output: 16 354 355

Beispiele Capture Lambdas Für Lambda-Expressions bestimmt die capture-liste über den zugreifbaren Teil des Kontextes int = 8; [](int v) {v += v; (); std::cout << ; Output: 8 Syntax: [x]: Zugriff auf opierten Wert von x (nur lesend) [&x]: Zugriff zur Referenz von x [&x,y]: Zugriff zur Referenz von x und zum opierten Wert von y [&]: Default-Referenz-Zugriff auf alle Objete im Scope der Lambda-Expression [=]: Default-Werte-Zugriff auf alle Objete im Kontext der Lambda-Expression 356 357 Capture Lambdas Capture Lambdas int elements=0; int sum=0; std::for_each(v.begin(), v.end(), [&] (int ) {sum += ; elements++; // capture all by reference ) template <typename T> void sequence(vector<int> & v, T done){ int i=0; while (!done()) v.push_bac(i++); vector<int> s; sequence(s, [&] {return s.size() >= 5; ) jetzt v = 0 1 2 3 4 Die capture liste bezieht sich auf den Kontext der Lambda Expression 358 359

Capture Lambdas Wann wird der Wert gelesen? int v = 42; auto func = [=] {std::cout << v << "\n"; v = 7; func(); Ausgabe: 42 Werte werden bei der Definition der (temporären) Lambda-Expression zugewiesen. Capture Lambdas (Warum) funtioniert das? class Limited{ int limit = 10; public: // count entries smaller than limit int count(const std::vector<int>& a){ int c = 0; std::for_each(a.begin(), a.end(), [=,&c] (int x) {if (x < limit) c++; ); return c; ; 360 Der this pointer wird per default implizit opiert 361 Capture Lambdas Lambda Ausdrüce sind Funtoren struct mutant{ int i = 0; void do(){ [=] {i=42;(); ; mutant m; m.do(); std::cout << m.i; Ausgabe: 42 Der this pointer wird per default implizit opiert [x, &y] () {y = x; ann implementiert werden als mit unnamed {x,y; class unnamed { int x; int& y; unnamed (int x_, int& y_) : x (x_), y (y_) { void operator () () {y = x;; ; 362 363

Lambda Ausdrüce sind Funtoren [=] () {return x + y; ann implementiert werden als mit unnamed {x,y; class unnamed { int x; int y; unnamed (int x_, int y_) : x (x_), y (y_) { int operator () () {return x + y; ; Polymorphic Function Wrapper std::function #include <functional> int = 8; std::function<int(int)> f; f = [](int i){ return i+; ; std::cout << f(8); // 16 Kann verwendet werden, um Lambda-Expressions zu speichern. Andere Beispiele std::function<int(int,int)>; std::function<void(double)>... http://en.cppreference.com/w/cpp/utility/functional/function 364 365