210 likes | 349 Views
Algoritmen en Datastructuren (ALDAT). EVMINX4 Week 4. Iterators. input iterator (single pass) een voor een lezen * (rvalue) ++ output iterator (single pass) een voor een schrijven * (lvalue) ++ forward iterator voorwaarts * ++ == != bidirectional iterator
E N D
Algoritmen en Datastructuren (ALDAT) EVMINX4 Week 4
Iterators input iterator (single pass) een voor een lezen * (rvalue) ++ output iterator (single pass) een voor een schrijven * (lvalue) ++ forward iterator voorwaarts * ++ == != bidirectional iterator voor-/achterwaarts * ++ --== != random access iterator met sprongen * ++ -- += -= + -== != > >= < <= [ ] een gewone pointer is een random access iterator Een iterator is geen class maar een (interface) afspraak. Elke class die aan deze afspraak voldoet is als iterator te gebruiken.
Iterators Relatie met containers bidirectional list, set, multiset, map en multimap random access vector en deque Relatie met algoritmes input bijvoorbeeld find output bijvoorbeeld copy forward bijvoorbeeld remove bidirectional bijvoorbeeld reverse random access bijvoorbeeld sort
Speciale iterators Insert-iterators (een soort cursor in insert mode). insert_iterator back_insert_iterator front_insert_iterator Stream-iterators (koppeling tussen iostream library en STL). istream_iterator ostream_iterator Dit zijn wel echte classes!
Speciale iteratorsvoorbeeld vector<int> rij; ifstream fin("getallen.txt"); istream_iterator<int> iin(fin); istream_iterator<int> einde; copy(iin, einde, back_inserter(rij)); sort(rij.begin(), rij.end()); ostream_iterator<int> iout(cout, " "); copy(rij.begin(), rij.end(), iout); Waarom werkt sort(iin, einde) niet?
Algoritmen Een algoritme werkt op een sequence. Een sequence wordt aangegeven door twee iteratoren i1 en i2. De sequence loopt van i1 tot (dus niet t/m) i2. vector<int> v; v.push_back(12); v.push_back(18); v.push_back(6); sort(v.begin(), v.end()); for (vector<int>::size_type i(0); i<v.size(); ++i) cout<<v[i]<<" ";
Algoritmen Zoeken van elementen find zoek element met bepaalde waarde O(n) find_if zoek element met bepaalde eigenschap find_first_of zoek element uit bepaalde sequence adjacent_find zoek twee opeenvolgende gelijke elementen Tellen van elementen count tel elementen met bepaalde waarde count_if tel elementen met bepaalde eigenschap Werken met elementen for_each voer bewerking uit op elk element Zoeken naar een sequence search zoek naar een sequence Vergelijken van sequences mismatch zoek eerste verschil in twee sequences equal vergelijk twee sequences (returntype is bool)
find #include <iostream> #include <vector> #include <algorithm> using namespace std; int main() { vector<int> v; v.push_back(-3); v.push_back(-4); v.push_back(3); v.push_back(4); vector<int>::iterator r; r=find(v.begin(), v.end(), -4); if (r!=v.end()) cout<<"Het eerste element met waarde –4 heeft index:“ <<r-v.begin()<<endl; cin.get(); return 0; }
find_if #include <iostream> #include <list> #include <algorithm> using namespace std; bool ispos(int i) { return i>=0; } int main() { list<int> l; l.push_back(-3);l.push_back(-4);l.push_back(3); l.push_back(4); list<int>::iterator r( find_if(l.begin(), l.end(), ispos) ); if (r!=l.end()) cout<<"Het eerste positieve element is:"<<*r<<endl; //… Function ispos is used as predicate Wat als we de eerste waarde >= 1 in de lijst l willen zoeken?
find_if //… class IsPos { public: bool operator()(int i) const { return i>=0; } }; int main() { list<int> l; l.push_back(-3);l.push_back(-4);l.push_back(3);l.push_back(4); list<int>::iterator r( find_if(l.begin(), l.end(), IsPos()) ); if (r!=l.end()) cout<<"Het eerste positieve element is:"<<*r<<endl; //... Functor IsPos() is used as predicateFunctor = object wat zich gedraagd als een functie
find_if //… class IsGreaterEqualInt { public: IsGreaterEqual(int e): e_(e) {} bool operator()(inte) const { return e>=e_; } private: int e_; }; int main() { list<int> l; l.push_back(-3);l.push_back(-4);l.push_back(3);l.push_back(4); list<int>::iterator( find_if(l.begin(), l.end(), IsGreaterEqualInt(0)) ); if (r!=l.end()) cout<<"Het eerste positieve element is:"<<*r<<endl; //... Functor IsGreaterEqualInt(0) is used as predicate 0 is nu variabel!
find_if //… template <typename T> class IsGreaterEqual { public: IsGreaterEqual(T e): e_(e) {} bool operator()(Te) const { return e>=e_; } private: T e_; }; int main() { list<int> l; l.push_back(-3);l.push_back(-4);l.push_back(3);l.push_back(4); list<int>::iterator( find_if(l.begin(), l.end(), IsGreaterEqual<int>(0)) ); if (r!=l.end()) cout<<"Het eerste positieve element is:"<<*r<<endl; //... Functor IsGreaterEqual<int>(0) is used as predicate int is nu een template parameter (compile time variabel) en 0 is nu variabel!
find_if #include <iostream> #include <list> #include <algorithm> #include <functional> int main() { list<int> l; l.push_back(-3);l.push_back(-4);l.push_back(3);l.push_back(4); list<int>::iterator( find_if(l.begin(), l.end(), bind2nd(greater_equal<int>(),0)) ); if (r!=l.end()) cout<<"Het eerste positieve element is:"<<*r<<endl; //... Functor bind2nd(greater_equal<int>(),0) is used as predicate
for_each #include <vector> #include <iostream> #include <iterator> #include <algorithm> using namespace std; void printDubbel(int i) { cout<<i<<" "<<i<<" "; } int main() { vector<int> v; v.push_back(-3);v.push_back(-4); v.push_back(3); v.push_back(4); ostream_iterator<int> iout(cout, " "); copy(v.begin(), v.end(), iout); cout<<endl; for_each(v.begin(), v.end(), printDubbel); cout<<endl; //…
Algoritmen (vervolg) Kopiëren copy kopieer elementen copy_if kopieer elementen met een bepaalde eigenschap Bewerken transform voer een binaire bewerking uit op twee sequences replace vervang elementen met een bepaalde waarde replace_if vervang elementen met een bepaalde eigenschap replace_copy copy gevolgd door replace replace_copy_if copy gevolgd door replace_if rotateroteer de elementen rotate_copy copy gevolgd door rotate random_shuffle schud de elementen (b.v. kaarten) Verwisselen swap_range verwissel sequences reverse keer de volgorde om reverse_copy copy gevolgd door reverse
transform //… #include <functional> #include <algorithm> using namespace std; int main() { vector<int> v, w; v.push_back(-3); v.push_back(-4); v.push_back(3); v.push_back(4); w.push_back(1); w.push_back(2); w.push_back(3); w.push_back(4); ostream_iterator<int> iout(cout, " "); copy(v.begin(), v.end(), iout); cout<<endl; // Bewerking opgeven met een functie. transform(v.begin(), v.end(), w.begin(),v.begin(), telop); copy(v.begin(), v.end(), iout); cout<<endl; // Bewerking opgeven met std functie-objecten. transform(v.begin(), v.end(), w.begin(),v.begin(), plus<int>()); copy(v.begin(), v.end(), iout); cout<<endl; int telop(int i, int j) { return i+j; }
Algoritmen (vervolg) Verwijderen remove “verwijder”1 elementen met bepaalde waarde remove_if “verwijder”1 elementen met bepaalde eigenschap remove_copy copy gevolgd door remove remove_copy_if copy gevolgd door remove_if unique “verwijder”1 alle elementen die gelijk zijn aan hun voorganger unique_copy copy gevolgd door unique Diversen fill maak alle elementen gelijk aan bepaalde waarde fill_n fill alleen de eerste n elementen generate maak alle elementen gelijk aan uitvoer van bepaalde functie generate_n generate alleen de eerste n elementen 1“verwijder” = verwijdert elementen niet echt (geeft iterator terug om te gebruiken in erase)
remove_if //… int main() { vector<int> v; for (int i(0); i<10; ++i) { v.push_back(i*i); } ostream_iterator<int> out(cout, " "); copy(v.begin(), v.end(), out); cout<<endl; vector<int>::iterator end( remove_if(v.begin(), v.end(), not1(bind2nd(modulus<int>(), 2))) ); copy(v.begin(), end, out); cout<<endl; copy(v.begin(), v.end(), out); cout<<endl; v.erase(end, v.end()); copy(v.begin(), v.end(), out); cout<<endl; // ... Uitvoer: 0 1 4 9 16 25 36 49 64 81 1 9 25 49 81 1 9 25 49 81 25 36 49 64 81 1 9 25 49 81
Algoritmen(vervolg) Sorteren sort sorteer elementen O(n•log n) stable_sort sorteer elementen (gelijke elementen worden niet verwisseld) binary_search zoek in een gesorteerde sequence O(log n) Set operations (werkt voor alle gesorteerde sequences) includes sequence1 sequence 2 set_union set_intersection set_difference – set_symmetric_difference Meer ...
mem_fun #include <iostream> #include <list> #include <algorithm> #include <functional> using namespace std; class Hond { public: virtual void blaf() const =0; ... }; class Tekkel: public Hond { ... }; class StBernard: public Hond { ... }; int main() { list<Hond*> k; k.push_back(new Tekkel); k.push_back(new StBernard); k.push_back(new Tekkel); for_each( k.begin(), k.end(), mem_fun(&Hond::blaf) ); ...