23.01.2003 Prof. Zavodnik/C++
Vorlesung/Kap X 1
STL macht es möglich
Ziel: Algorithmen, unabhängig von Containerklassen zu schreiben
Methode: Templates mit formalen Iteratorparameter schreiben
Auch Typen und
Klassenfunktionen als Parameter
zulassen
23.01.2003 Prof. Zavodnik/C++
Vorlesung/Kap X 3
Es gibt 5 verschiedene Iterator-typen InputIterator: !=, ==, ++ und *.
Dereferenzierung ist read-only
OutputIterator : Wie Input, nur De- refenzierung ist write-enable
ForwardIterator : Ist InputIterator und
OutputIterator in eine Richtung
BidirectionalIterator : Wie Forward, aber Durchlauf ist in
beiden Richtungen erlaubt, also ++
und – sind erlaubt
RandomAccessIterator :
Addition und Subtrtaktion mit int ,
überladener [] , Vergleiche
23.01.2003 Prof. Zavodnik/C++
Vorlesung/Kap X 5
Alle generischen Algorithmen operieren indirekt auf den
Elementen von Containern über diese Iteratoren
Klassenfunktionen können auch
herangezogen werden
Auch Function Objects für entsprechende Objekte genannt Werden in Klassen durch
Überladung des Klammeroperators () definiert
Warum? Weil Information für den generischen Algorithmus
vorhanden ist. Auch Effizienz
Normale Funktionen auch möglich
23.01.2003 Prof. Zavodnik/C++
Vorlesung/Kap X 7
Normale Funktion
int sumSquares(int total, int value) {
return total + value*value;
}
Klassenfunktion
template <class T>
class sumSquaresClass : public binary_function {
public:
const T operator()(const T& total, const T value) {
return total + value*value;
}
…
23.01.2003 Prof. Zavodnik/C++
Vorlesung/Kap X 9
accumulate
template <class InputIterator, class Type, class BinaryOperator>
Type accumulate(InputIterator first, InputIterator last, Type initVal,
BinaryOperator op) {
while (first != last){ initVal = op(initVal, *first); ++first;}
return initVal;
}
! " accumulate
1. Bei normalen Funktionen
int Tabelle[50] = { … };
int sum = 0;
sum = accumulate(Tabelle, Tabelle + 50, 0, sumSquares);
2. Bei Klassenfunktionen
int Tabelle[50] = { … };
int sum = 0;
sum = accumulate(Tabelle, Tabelle + 50, 0, sumSquaresClass<int>()),
23.01.2003 Prof. Zavodnik/C++
Vorlesung/Kap X 11
# map
Ähnlich zu C++-Reihung, aber Index ist ein Schlüssel
Es gibt zwei Typen
Der Schlüsseltyp Der Typ des Bildes
Unterschied zu Reihungen:
Bildelemente sind nur für
vorhandenen Schlüssel definiert
(schwachbesetzte Darstellung)
$ % " " &
map
Schlüsselvergleich (Compare)
Wertvergleich (value_compare) ist Funktionsobjekt
Überladener Operator []
23.01.2003 Prof. Zavodnik/C++
Vorlesung/Kap X 13
' !
Gewichte werden Kanten zugewiesen Konsequenz: Zwei Knoten sind
erforderlich, um einen Kantenwert darstellen zu können
Annahme: Knoten sind durch (C++) string s ettiketiert
Definition in zwei Schritten
map<string, int> ist Zuweisung string --> int
map<string, map<string,int>> ist
korrekt
(
Gegeben:
Landkarte mit n Städten
Abstand zwischen je zwei Städten
Gesucht: Die Wege von einem festen
Knoten zu allen anderen Knoten, welche die geringste Summe der
Kantengewichte besitzen
Jeder Knoten darf nur einmal
durchschritten werden
23.01.2003 Prof. Zavodnik/C++
Vorlesung/Kap X 15
) ! "
* + ,
Sortiertes Einfügen: kleinstes, bzw.
größtes Element immer vorn
Abstand von einem festen v
0zu einem Knoten v wird in eine sog.
pair -Struktur eingetragen:
struct distancePair{
unsigned int first;
string second;
...
};
v0 sei fest
gesucht:distances[u] = kürzestes Abstand von v0 nach u distances[v0] = 0;
push(0,v0);
while (priority_queue nicht leer)
1. pop kleinstes Paar P der priority_queue;
city = P.second;
Abstand = P.first;
2. if (distances[city] nicht definiert) distances[city] = Abstand;
else übergehen
3. for (jede Stadt u für welche distance[u] nicht definiert)
23.01.2003 Prof. Zavodnik/C++
Vorlesung/Kap X 17
- . * "
typedef map<string, int> stringVector typedef map<string, stringVector> graph;
graph cityMap;
-
stringVector distances;
class distancePair : pair<int, string>{
public:
unsigned int first;
string second;
distancePair():first(0){}
distancePair(unsigned int f, string s): first(f), second(s){}};
bool operator > (distancePair, lhs, distancePair rhs) {
return lhs.first > rhs.first;
}
priority_queue<distancePair, vector<distancePair>,
23.01.2003 Prof. Zavodnik/C++
Vorlesung/Kap X 19
-
int main() {
//initialisiere cityMap string start = ...;
que.push(Object);
while(!queue.empty()){
dummy = que.top();
int distance = dummy.first; string city = dummy.second;
que.pop();
if (!distances.count(city)){
distances[city] = distance;
for(stringVector::iterator start = cityMap[city].begin();
start != cityMap[city].end(); ++start){
int i = (*start).second; //in stringVector string st = (*start).first;
que.push(distancePair(distance + i, st)); } }}
//Lösung ausdrucken return 0;}
Wolfsegg
Zeitlarn
Wenzenbach
Regenstauf
Regensburg Donaustauf
Bernhardswald Pielenhofen
2
8
4
3 3
4
3 10
5
4
2 5
23.01.2003 Prof. Zavodnik/C++
Vorlesung/Kap X 21