Programmierkurs ( Wintersemester 2017 ) Aufgabenblatt 9 Dr. Ole Klein, Dr. Steffen Müthing Abgabe 26. Januar 2018 IWR, Universität Heidelberg

Ähnliche Dokumente
Aufgabenblatt 11 Musterlösung

Probeklausur. Musterlösung

Programmierkurs. Steffen Müthing. January 18, Interdisciplinary Center for Scientific Computing, Heidelberg University

Programmierkurs ( Wintersemester 2017 ) Aufgabenblatt 3 Dr. Ole Klein, Dr. Steffen Müthing Abgabe 20. November 2017 IWR, Universität Heidelberg

Vorlesungsprüfung Programmiersprache 1

Programmierkurs. Steffen Müthing. December 7, Interdisciplinary Center for Scientific Computing, Heidelberg University

Abend 4 Übung : Erweitern von Klassen durch Vererbung

Polymorphismus 179. Function.h. #include <string>

Unterlagen. CPP-Uebungen-08/

C++ Kurs Teil 3. Standard Template Library (STL) Kommunikation mit der shell Hyper Text Markup Language (HTML)

Polymorphismus 44. Function.hpp. #include <string>

Objektorientierte Programmierung mit C++ SS 2007

Programmieren in C++ Templates

Programmiertechnik. Teil 4. C++ Funktionen: Prototypen Overloading Parameter. C++ Funktionen: Eigenschaften

C++ Notnagel. Ziel, Inhalt. Programmieren in C++

Programmierkurs. Steffen Müthing. January 25, Interdisciplinary Center for Scientific Computing, Heidelberg University

Informatik für Mathematiker und Physiker Woche 7. David Sommer

Pascal Schärli

Ein kleiner Blick auf die generische Programmierung

Informatik - Übungsstunde

Informatik I (D-ITET)

A practical guide to C++

Programmier-Befehle - Woche 08

Programmier-Befehle - Woche 10

Informatik 1 ( ) D-MAVT F2010. Letzte Übungsstunde. Yves Brise Übungsstunde 12

Schlussendlich geben wir die Listen aus. Es kommt zu folgender Ausgabe:

Programmierkurs. Steffen Müthing. November 16, Interdisciplinary Center for Scientific Computing, Heidelberg University

Repetitorium Programmieren I + II

Praktikum zu Einführung in die Informatik für LogWiIngs und WiMas Wintersemester 2017/18. Vorbereitende Aufgaben

3 Dateien 5. 4 Aufgaben 5. 5 Ausblick 6. Wir wenden uns der Implementierung von Datenstrukturen mittels objekt-orientierter Programmierung

Lambda-Funktionen. Lambda-Funktionen. Lambda-Funktionen sollen

Vererbung I. Kfz Eigenschaften und Methoden der Klasse Kfz Lkw. Pkw. Eigenschaften und Methoden der Klasse Kfz

Ziele sind das Arbeiten mit Funktionen (Modularisierung, Parameterübergabe), sowie - Reihentyp (Array)

Informatik - Übungsstunde

Programmiersprache 1 (C++) Prof. Dr. Stefan Enderle NTA Isny

hue12 January 24, 2017

Übung Augmented Reality

DAP2 Praktikum Blatt 1

Praktikum zu Einführung in die Informatik für LogWiIngs und WiMas Wintersemester 2016/17. Vorbereitende Aufgaben

Modernes C++ Compilation Firewall Exception-Safe Function Calls. Philippe Lieser

Copy-on-write und Implicit Sharing in Qt

Hochschule Darmstadt Informatik-Praktikum SS 2018 EIT Bachelor 3. Aufgabenblatt Funktionen - Unterprogramme

Praktikum zur Vorlesung Einführung in die Programmierung WS 14/15 Blatt 3

Grundkurs C++ IDE Klassenhierarchien

Dynamische Datentypen. Destruktor, Copy-Konstruktor, Zuweisungsoperator, Dynamischer Datentyp, Vektoren

Themen. Formatierte und unformatierte Eingabe Bedingungsoperator Namespaces Kommandozeilenargumente

Grundkurs C++ IDE Klassenhierarchien

Programmierkurs C/C++

Klausur Grundlagen der Programmierung

Praktikum 4: Delegation

Objektorientierte Programmierung mit C++ den sog. default constructor X (){}

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

Informatik 1 ( ) D-MAVT F2010. Klassen. Yves Brise Übungsstunde 9

Microcontroller / C-Programmierung Selbststudium Semesterwoche 1

Prüfung A Informatik D-MATH/D-PHYS :15 14:55

Programmierkurs. Steffen Müthing. November 30, Interdisciplinary Center for Scientific Computing, Heidelberg University

Programmieren II Abstrakte Klassen / Virtuelle Methoden. Programmieren II Abstrakte Klassen / Virtuelle Methoden

Übungsblatt 1. Java Vorkurs (WS 2017)

10.4 Konstante Objekte

GI Vektoren

Grundkurs C++ IDE Klassenhierarchien

Vererbung und Polymorphie

Wie teuer ist dynamischer Polymorphismus? 194

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

Hochschule Darmstadt Informatik-Praktikum WS 2017/2018 EIT Bachelor 5. Aufgabenblatt Datenstruktur, Dateieingabe und -ausgabe

Wintersemester Maschinenbau und Kunststofftechnik. Informatik. Tobias Wolf Seite 1 von 29

Hilfsblatt für C++ Prüfungen im 5. Semester

initializer lists (nicht für Referenzen... unklar warum...)

Programmieren in Java

Grundlagen C und C++ Einheit 04: Weitere Grundlagen in C++ Lorenz Schauer Lehrstuhl für Mobile und Verteilte Systeme

Grundlagen der Informatik

Praxisorientierte Einführung in C++ Lektion: "Virtuelle Methoden"

Übungsstunde: Informatik 1 D-MAVT

Praktikum zu Einführung in die Informatik für LogWiIngs und WiMas Wintersemester 2018/19. Vorbereitende Aufgaben

Übungen zum Bioinformatik-Tutorium. Blatt 3

Einführung Sprachfeatures Hinweise, Tipps und Styleguide Informationen. Einführung in C. Patrick Schulz

Hochschule Darmstadt Informatik-Praktikum WS 2017/2018 WIng Bachelor 6. Aufgabenblatt Zeiger, verkettete Liste, Dateieingabe und -ausgabe

Visuelle Kryptographie. Anwendung von Zufallszahlen

C++ Teil 7. Sven Groß. 30. Nov Sven Groß (IGPM, RWTH Aachen) C++ Teil Nov / 13

Zusammenfassung. Mit bjam und ein paar Zeilen in einem Jamroot oder Jamfile lässt sich das Kompilieren und Linken einfach automatisieren

Verschlüsseln eines Bildes. Visuelle Kryptographie. Verschlüsseln eines Bildes. Verschlüsseln eines Bildes

Polymorphe for-anweisung 237

kurze Wiederholung class templates

Java Tools JDK. IDEs. Downloads. Eclipse. IntelliJ. NetBeans. Java SE 8 Java SE 8 Documentation

Übung Notendarstellung

Angewandte Mathematik und Programmierung

Übungspaket 12 Der Datentyp char

hue13 January 30, 2017

hue06 December 2, 2016

Hausaufgabe 5. Informatik 1 Wintersemester 2015/16

Übung zur Vorlesung EidP (WS 2018/19) Blatt 4

OOP und Angewandte Mathematik. Eine Einführung in die Anwendung objektorientierter Konzepte in der angewandten Mathematik

Quiz und Übungen. C++ Übung am 19. Mai 2016

Hochschule Darmstadt Informatik-Praktikum SS 2017 EIT Bachelor 5. Aufgabenblatt Datenstruktur, Dateieingabe und -ausgabe

Vorbereitende Aufgaben

Klausur Kompaktkurs Einführung in die Programmierung Dr. T. Weinzierl & M. Sedlacek 25. März 2011

JAVA BASICS. 2. Primitive Datentypen. 1. Warum Java? a) Boolean (logische Werte wahr & falsch)

16. Structs und Klassen I. Rationale Zahlen, Struct-Definition, Operator-Überladung, Datenkapselung, Klassen-Typen

Einführung in die Programmierung mit C++

Transkript:

Programmierkurs ( Wintersemester 2017 ) Aufgabenblatt 9 Dr. Ole Klein, Dr. Steffen Müthing Abgabe 26. Januar 2018 IWR, Universität Heidelberg Übung 1 Templates 101 In einer früheren Aufgabe haben Sie die Template-Funktion std::swap() verwendet, die Referenzen auf zwei Variablen gleichen Typs bekommt und diese vertauscht (dafür wird eine temporäre Variable angelegt). Schreiben Sie Ihre eigene Version der Funktion (ebenfalls als Template), mit der folgende main()-funktion korrekt funktioniert: 1 int main(int argc, char** argv) 2 { 3 int a = 1; 4 int b = 2; 5 std::cout << "a = " << a << " b = " << b << std::endl; 6 swap(a,b); 7 std::cout << "a = " << a << " b = " << b << std::endl; 8 double c = 3; 9 double d = 4; 10 std::cout << "c = " << c << " d = " << d << std::endl; 11 swap(c,d); 12 std::cout << "c = " << c << " d = " << d << std::endl; 13 return 0; 14 } Stellen Sie sicher, dass der Code nicht mehr kompiliert, wenn Sie folgende Zeile hinzufügen: 1 swap(a,c); ( Grundlagen und Fortgeschritten ) Übung 2 Wiederverwendbare Wortfrequenzen Auf einem früheren Blatt haben Sie ein Programm geschrieben, um die Häufigkeit von Buchstaben bzw. Wörtern auszuwerten. Im folgenden werden wir dieses Programm in eine wiederverwendbare Klasse umwandeln. Verwenden Sie hierfür folgendes Interface: 1 template<typename Map> 2 class LetterFrequencies { 3 4 public: 5 6 // Processes all letters obtained from source 7 template<typename Source> 8 void readdata(source& source); 9 10 // does the statistics and prints to stdout

11 void printstatistics(); 12 13 }; Source soll hierbei das Konzept einer speziellen Klasse erfüllen, die einfach Buchstaben oder Wörter aus einem Eingabe-Stream einliest (z.b. der Standardeingabe oder einer Datei) und diese dann jeweils einzeln zurückliefert. Konkret funktioniert folgendes: 1 auto source = streamwordsource(std::cin); 2 while (true) 3 { 4 auto data = source.next(); 5 // check if data valid 6 if (not data.second) 7 break; 8 9 // work with actual data 10.. 11 _map[data.first] += 1; 12 } Der Rückgabewert von Source::next() ist je nach Variante ein std::pair<char,bool> bzw. std::pair<std::string,bool>. Sie können fertige Implementierungen derartiger Sources von der Vorlesungs-Homepage herunterladen: 1. Sie können für jede der folgenden Teilaufgaben jeweils einzeln votieren: (a) Portieren Sie Ihren Code aus der vorherigen Aufgabe in die Klasse LetterFrequencies und schreiben Sie ein passendes Testprogramm. Schreiben Sie ausserdem ein zweites Testprogramm, dem man auf der Kommandozeile mehrere Dateinamen mitgeben kann und das dann eine gemeinsame Statistik für den Inhalt aller Dateien ausgibt. Verwenden Sie hierfür die Source mit einem std::ifstream als unterliegendem Stream. Um über die Argumente der Kommandozeile zu iterieren, verwenden Sie folgenden Code: 1 for (int i = 1 ; i < argc ; ++i) 2 { 3 std::ifstream f(argv[i]); 4 auto source = streamlettersource(f); 5... 6 } Testen Sie Ihre Klasse sowohl mit std::map als auch mit std::unordered_map! Hinweis: Sie müssen dem public Interface der Klasse von weiter oben noch private Member- Variablen und nach Bedarf weitere Member-Funktionen hinzufügen! (b) Kopieren Sie Ihre Klasse und erstellen eine allgemeinere Klasse Frequencies. Diese soll den zu analysierenden C++-Type (char oder std::string) aus der Map extrahieren (verfügbar als typename Map::key_type) und als typedef exportieren. Dieser Typ soll überall in der Klasse verwendet werden, so dass man mit der Klasse sowohl Buchstaben als auch Wörter analysieren kann. Hierfür muss allerdings das Postprocessing (Gross-Kleinschreibung, Filtern etc.) austauschbar sein. Fügen Sie hierzu Ihrer Klasse einen zweiten Template-Parameter Filter hinzu. Filter soll eine Klasse sein, die folgendes Konzept erfüllt: 1 class Filter { 2 public: 3 // takes the input data and returns a transformed 1 https://conan.iwr.uni-heidelberg.de/data/teaching/ipk_ws2017/frequencysource.hh

4 // version (e.g. capitalizes all letters) 5 Data transform(const Data& data); 6 7 // decides whether the input letter or word should be 8 // removed from the statistics (not added to the map) 9 bool remove(const Data& data); 10 }; Data ist hier entweder char oder std::string, je nachdem, wofür der Filter geschrieben wurde. Schreiben Sie für beide Varianten jeweils einen passenden Filter, der den Code enthält, der in der vorherigen Aufgabe in den verschiedenen Versionen von get_frequencies() für das Verarbeiten der Daten verantwortlich war. Die Klasse Frequencies sollte im Konstruktor eine Kopie des Filters bekommen und diese als Member-Variable speichern. In process() rufen Sie dann die jeweiligen Methoden von Filter auf, statt direkt etwas an den Buchstaben / Wörtern zu verändern. Testen Sie, ob Ihre Implementierung sowohl für Buchstaben als auch für Wörter funktioniert. Hinweis: Sie müssen dem public Interface der Klasse auch hier noch private Member- Variablen und nach Bedarf weitere Member-Funktionen hinzufügen! (c) Bonus: Sie haben bereits verschiedene Ausgaben für Ihr Programm geschrieben (Listen und Histogramme). Theoretisch könnte man sich hier weitere ausdenken oder zur Laufzeit entscheiden, welche Ausgaben man haben möchte. Derartige optionale Fähigkeiten, die alle ein gemeinsames Interface erfüllen, werden oft mit Hilfe sogenannter Plugins realisiert. Plugins sind kleine Softwarebausteine, die auf wohldefinierte Weise mit dem eigentlichen Programm interagieren und diesem nach Belieben hinzugefügt werden können. Wir werden im folgenden ein sehr einfaches Plugin verwenden: 1 template<typename Map> 2 class AnalysisPlugin { 3 4 public: 5 6 using Data = typename Map::key_type; 7 8 // always add virtual destructor 9 virtual ~Plugin() 10 {} 11 12 // returns the name of the plugin 13 virtual std::string name() const = 0; 14 15 // does some statistics on the map and prints it to stdout 16 virtual void printstatistics(const Map& map) 17 { 18 // do nothing by default 19 } 20 21 }; Schreiben Sie zwei Plugins PrintFrequencies und PrintTotalCount, die von AnalysisPlugin erben und eine Liste der Buchstaben/Wörter mit Ihrer Häufigkeit bzw. die Gesamtzahl an Buchstaben/Wörtern ausgeben. Hinweis: Die Plugins sind selbst Templates und müssen von der korrekten Instantiierung der Basisklasse erben:

1 template<typename Map> 2 class PrintTotalCount 3 : public AnalysisPlugin<Map> 4 {... }; (d) Bonus: Fügen Sie Ihrer Frequencies-Klasse folgenden Code hinzu, um mit Plugins arbeiten zu können: 1 #include <memory> 2 3 template<typename Map, typename Filter> 4 class Frequencies 5 { 6 public: 7 8 // abstract Plugin base type 9 using Plugin = AnalysisPlugin<Map>; 10 11 // add a new plugin 12 void addplugin(const std::shared_ptr<plugin> plugin) 13 { 14 _plugins.push_back(plugin); 15 } 16 17 private: 18 std::vector<std::shared_ptr<plugin>> _plugins; 19 }; std::shared_ptr ist ein sogenannter smart pointer. Er verhält sich wie ein normaler Pointer, aber kümmert sich automatisch um das Allokieren und Freigeben von Speicher. Um ein Plugin anzulegen bzw. aufzurufen, verwenden Sie folgenden Code: 1 // define type of map to be used (at the beginning of the program) 2 using WordMap = std::unordered_map<std::string,int>; 3 // create custom word filter (exercise (b) ) 4 WordFilter wordfilter; 5 // create main class 6 Frequencies<WordMap,WordFilter> frequencies(wordfilter); 7 // add plugin of type PrintTotalCount<Map> 8 frequencies.addplugin( 9 std::make_shared<printtotalcount<map>>()); 10 11... 12 13 // inside Frequencies: plugin is a pointer, so need to dereference! 14 for (auto& plugin : _plugins) 15 plugin->analyze(); Schreiben Sie die analyze()-funktion in Frequencies so um, dass Sie über alle Plugins iteriert, den Namen des Plugins ausgibt und dann die Analyse-Funktion des Plugins aufruft. (e) Bonus: Schreiben Sie ein Plugin, dass ein Histogramm der Daten ausgibt. ( Grundlagen )

Übung 3 Fortgeschrittene Ein- und Ausgabe von Dateien Im Rahmen der Anfängeraufgaben wurden die Dateien pgm.hh und pgm.cc zur Verfügung gestellt, um Bilder im PGM-Format lesen und schreiben zu können. Dieser Code erzeugt ASCII-Dateien, was für das Üben und das Debuggen sehr hilfreich ist, aber gleichzeitig einiges an Speicherplatz verschwendet. Unter http://netpbm.sourceforge.net/doc/pgm.html finden Sie die offizielle Spezifikation von PGM. Verwenden Sie diese, um die vorliegenden Dateien um folgende Funktionalität zu erweitern: Eine Möglichkeit, zwischen ASCII-I/O (bereits vorhanden) und binärer Ein- und Ausgabe zu wählen. Informieren Sie sich dazu darüber, wie man mit C++ Byte-Sequenzen aus Dateien liest bzw. sie schreibt. Verwenden Sie moderne C++-Stream-Klassen, keine C-Handles! Für den in jedem Fall vorhandenen ASCII-Header kann es bei der Ausgabe vorteilhaft sein, zunächst einen std::string zu erstellen, statt mit char-pointern zu hantieren. Die Option, statt einfachen Pixelwerten eine Ein-/Ausgabe mit Gamma-Adjustment zu verwenden, wie in der Spezifikation erwähnt ( true PGM ). Die Umrechnungsformel dafür finden Sie auf Wikipedia 2. (Der erwähnte Wert 2.2 für Gamma ist dabei die Inverse des Exponenten.) Bei der Ausgabe soll der Datenbereich falls nötig so verschoben werden, dass keine negativen Werte mehr auftreten, und danach so gestaucht, dass die Werte in den darstellbaren Bereich passen (letzteres ist bereits vorhanden). Hinweise: Es soll möglich sein, diese Optionen beliebig zu kombinieren. Bei der Eingabe können Sie davon ausgehen, dass die Datei keine Kommentare enthält, damit es leichter ist, den Header zu parsen. Beim Debuggen kann es hilfreich sein, mittels pgmtopgm -plain die von Ihnen erzeugte Datei in ein ASCII-PGM umzuwandeln, um sehen zu können, was genau im Byte-Stream steht. ( Fortgeschritten ) 2 https://en.wikipedia.org/wiki/rec._709#transfer_characteristics