Einführung in die STL anhand eines ausgewählten Beispiels
Transcription
Einführung in die STL anhand eines ausgewählten Beispiels
Einführung in die STL anhand eines ausgewählten Beispiels Frank M. Thiesing http://home.t-online.de/home/ frank.thiesing/STL/STL-Folien.pdf Inhalt n n n n n n n Überblick über die C++ STL Container Iteratoren Algorithmen Erweiterungen der STL Tipps und Tricks Weiterführende Literatur Überblick STL n n n n n C++ Standard-Template-Library Herzstück der C++ Standardbibliothek Daten-Behälter (Container) für effiziente Mengenverarbeitung Templates: Schablonen für generische Datenstrukturen und Algorithmen Standardisierte, deshalb einheitliche Schnittstelle Bestandteile der STL Algorithmen Iteratoren Container for_each(), find(), transform(), sort(), ... Sequentielle Container Vector: Deque: List: Assoziative Container Set/Multiset: Intern: Balancierter Binärbaum 4 Map/Multimap: 2 1 6 3 5 Bsp.: Vector #include <iostream> #include <vector> using namespace std; int main() { vector<int> menge; 1 2 3 4 5 6 // Vector-Container fuer int for (int i=1; i<=6; i++) { menge.push_back(i); } } for (int i=0; i<menge.size(); i++) { cout << menge[i] << ' '; } cout << endl; Ausgabe: „1 2 3 4 5 6“ Bsp.: Deque #include <iostream> #include <deque> using namespace std; int main() { deque<float> menge; 3.32.21.11.12.23.3 // Deque-Container fuer float for (int i=1; i<=3; i++) { menge.push_front(i*1.1); menge.push_back(i*1.1); } for (int i=0; i<menge.size(); i++) { cout << menge[i] << ' '; } cout << endl; Ausgabe: „3.3 2.2 1.1 1.1 2.2 3.3“ } Bsp.: List #include <iostream> #include <list> using namespace std; int main() { list<char> menge; a b c ... y // List-Container fuer char for (char c='a'; c<='z'; c++) { menge.push_back(c); } while (! menge.empty()) { cout << menge.front() << ' '; menge.pop_front(); } cout << endl; Ausgabe: „a b c ... y z“ } z Iteratoren n Wie Zeiger in C/C++: n n n Iterator::operator*() Iterator::operator++() Iterator::operator==() begin() pos ++ end() Bsp.: List mit Iteratoren #include <iostream> begin() pos end() ++ #include <list> #include <iterator> using namespace std; int main() a b c ... y z { list<char> menge; for (char c='a'; c<='z'; c++) { menge.push_back(c); } list<char>::iterator pos; for (pos = menge.begin(); pos != menge.end(); ++pos) { cout << *pos << ' '; } cout << endl; Ausgabe: „a b c ... y z“ } Bsp.: Set #include <set> using namespace std; pos ++ int main() { typedef set<int> IntSet; IntSet menge; menge.insert (3); 4 menge.insert (1); menge.insert (5); 2 6 menge.insert (4); menge.insert (6); 1 3 5 menge.insert (2); IntSet::iterator pos; for (pos = menge.begin(); pos != menge.end(); ++pos) { cout << *pos << ' '; } cout << endl; Ausgabe: „1 2 3 4 5 6“ } Map (= assoziatives Array) Aktie: BASF Kurs: 123.5 #include <map> #include <string> Aktie: BMW Kurs: 67.5 using namespace std; Aktie: VW Kurs: 98.5 int main() { typedef map<string,float> StringFloatMap; StringFloatMap aktien; aktien["BASF"] = 123.5; aktien.insert(pair<const string,float>("VW",98.5)); aktien.insert(StringFloatMap::value_type ("BWM",67.5)); } StringFloatMap::iterator pos; for (pos = aktien.begin(); pos != aktien.end(); ++pos) { cout << "Aktie: " << pos->first << '\t' << "Kurs: " << pos->second << endl; } Kategorisierung von Iteratoren n Bidirectional-Iteratoren n n n Random-Access-Iteratoren n n n n operator++ und operator-Vergleich mit ==, != Wahlfreier Zugriff Vergleich auch mit <, > Insert-Iteratoren Output- und Stream-Iteratoren begin() end() Algorithmen 2 5 4 1 6 3 #include <algorithm> void print (int elem) { cout << elem << ' ';} ... vector<int> menge; vector<int>::iterator pos, pos5; ... pos = min_element (menge.begin(), menge.end()); pos5 = find (menge.begin(), menge.end(), 5); reverse (pos5, menge.end()); 2 3 6 1 4 5 sort (menge.begin()+1, menge.end()-1); 2 1 3 4 6 5 for_each (menge.begin(), menge.end(), print); Einfügen und Löschen #include <vector> begin() pos1 #include <algorithm> ... 2 5 4 1 6 3 vector<int> menge; vector<int>::iterator pos1, ende; end() pos1 = find (menge.begin(), menge.end(), 1); inserter (menge, pos1) = 7; 2 5 4 7 1 6 3 ende = remove (menge.begin(), menge.end(), 4); ende 2 5 7 1 6 3 3 menge.erase (ende, menge.end()); 2 5 7 1 6 3 Container-Elemente n Anforderungen n n n n Copy-Konstruktor Zuweisungsoperator Destruktor Weitere Anforderungen n n n Default-Konstruktor Vergleichsoperator == Operator < für automatische Sortierung Erweiterungen der STL n n STL ist offen für eigene Erweiterungen Schon da: Container-Adapter für n n n Queue (=Schlange, FIFO) (deque oder list) Priority-Queue (vector oder deque als Heap) Stack (=Keller, LIFO) (vector, deque oder list) Beispiel: Stack über List: #include <stack> ... stack<string,list<string>> keller; keller.push("Hallo"); cout << keller.top(); keller.pop(); Hallo xyz abc Tipps und Tricks n Keine Zeiger als Container-Elemente! n n n n n Fehlerbehandlung in der STL n n n Container arbeiten mit Kopien der Werte Positiv: keine Probleme mit Verweisen Negativ: Kopieren dauert seine Zeit Negativ: Elemente nur in einem Container Keine Überprüfungen zur Laufzeit Am besten, man macht keine Fehler! Wann benutzt man welchen Container? Zum Nachlesen n n http://home.t-online.de/home/ frank.thiesing/STL/STL.html Nicolai Josuttis: Die C++ Standardbibliothek Addison-Wesley, 1996 n Ulrich Breymann: Komponenten entwerfen mit der C++ STL 2. Auflage, Addison-Wesley, 1999