1 / 36

An Introduction to STL - Standard Template Library

Learn about the C++ Standard Template Library (STL), its advantages, basic concepts, and examples of using STL containers and iterators in C++ programming. Understand when to use vector, deque, and list STL containers for efficient data handling and manipulation in your projects.

Download Presentation

An Introduction to STL - Standard Template Library

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. An Introduction to STL - Standard Template Library Jiang Hu Department of Electrical Engineering Texas A&M University

  2. What Is STL? • C++ based implementations of general purpose data structures and algorithms

  3. When Do You Need STL? • Reduce your C/C++ programming time • Use data structures and algorithms from STL directly, instead of implementing everything from scratch • Easier maintenance • Bugs in bottom structures are the most difficult to find • Use STL as building blocks, they are robust • Program runtime is not very critical • General purpose implementations may run a little slower than customized implementations

  4. Assumption • You know basics of • C++ • Data structures such as link list, hash table, binary search tree … • Algorithms such as sorting …

  5. Bottom Line: Understand class • class is • An essential concept for C++ • What STL is built on • An abstract form • Has member variables to record data • Has member functions to do something • Members can be open to public or encapsulated to be private

  6. class node { private: long x, y, ID; double rat, cap; node* parent; public: node(long id); void setCoordinates( long, long ); long getID(); }; node::node(long id) : x(0), y(0), ID(id), parent(NULL) {} long node::getID() { return ID; } main() { node myNode(1); myNode.setCoordinates(5,8); long p = myNode.getID(); } Example of class

  7. STL Containers • Sequence containers • vector • deque • list • Sorted associative containers • set • multiset • map • multimap

  8. STL list • list is a list • Functionally, similar to double-linked list • Supports • Insertion • Deletion • Sorting • … …

  9. Example of list #include <list.h> void doSomething() { list<node> nodeList; … … nodeList.push_back( node(1) ); // node1 is added at end nodeList.push_front( node(0) ); // node0 is added at front nodeList.pop_back(); // remove the element at end nodeList.pop_front(); // remove the element at front … … }

  10. STL iterator begin() #include <list.h> void doSomething() { list<node> nodeList; list<node>::iterator j; // Generalized pointer … … for ( j = nodeList.begin(); j != nodeList.end(); j++ ) { if ( (*j).getID() > 3 ) break; } … … } end() list

  11. insert(), erase() and remove() #include <list.h> void doSomething() { list<node> nodeList; list<node>::iterator j; // Generalized pointer … … for ( j = nodeList.begin(); j != nodeList.end(); j++ ) { if ( (*j).getID() > 3 ) nodeList.insert( j, node(2) ); if ( (*j).getID() < 0 ) nodeList.erase( j ); // problem?? } nodeList.remove( nodeA ); // operator== defined for node … … }

  12. Carefulerase in a loop #include <list.h> void doSomething() { list<node> nodeList; list<node>::iterator j, k; … … j = nodeList.begin(); while ( j != nodeList.end() ) { k = j++; if ( (*k).getID() < 0 ) { nodeList.erase( k ); } } … … }

  13. front() and back() #include <list.h> void doSomething() { list<node> nodeList; … … node A = nodeList.front(); // copy the first node in the list node B( nodeList.back() ); // construct a node B same as // the last node in the list … … }

  14. size(), sort() and merge() #include <list.h> void doSomething() { list<node> listA, listB; … … int numNodes = listA.size(); // number of elements in list listA.sort(); // operator< is defined for node listB.sort(); listA.merge( listB ); // both lists should be sorted // listB becomes empty after merge … … }

  15. STL vector • Functionality-wise, roughly a subset of list • No push_front(), pop_front(), remove(), sort(), merge() • Supports operator [], such as vectorA[3] • Thenwhy need vector ? • Faster access if the data are mostly static or not much insertion/deletion

  16. STL deque • Very similar to vector, except • Supports push_front() and pop_front() • No operator [] • Also friendly to accessing static data

  17. vector vs. array in C/C++ • Dynamic memory management for vector • Certain size of memory is allocated when a vector is constructed • When add a new element and the memory space is insufficient, multiple-sized new memory is allocated automatically

  18. Use reserve() if possible • If you have a rough idea of the size of the vector, use reserve() to allocate sufficient memory space at the beginning • Dynamic memory allocation is nice, but it costs you runtime, the related copying also takes time • Ex., you will work on a routing tree for a net with k sinks, then: vector<node> nodeVec; const int a = 2; nodeVec.reserve( a*k );

  19. Sequence Container Summary • Contiguous-memory based: • vector, constant time addition and deletion at end • deque, constant time addition and deletion at beginning and end • Constant time access • Linear time insertion/deletion in middle • Node based – list • Linear time access • Constant time insertion/deletion any position

  20. Sorted Associative Containers • set<key> : a set of sorted key which can be any data type with operator< defined • multiset<key> : allow duplicative keys • map<key, T> : T is a certain data type, the data are always sorted according to their keys • multimap<key, T> : allow duplicative keys • Internally, implemented via red-black tree

  21. STL map #include <map.h> void doSomething() { map<string, double, less<string> > tempMap; tempMap[ “Austin” ] = 93.2; // [] can be employed to insert tempMap.insert( pair<string,double>( “Chicago”, 84.6 ) ); tempMap[ “Chicago” ] = 86.8; // [] is better for update map<string, double, less<string> >::iterator k; for ( k = tempMap.begin(); k != tempMap.end(); k++ ) { if ( (*k).first == “Austin” ) (*k).second = 97.4; } k = tempMap.find( “Austin” ); if ( k != tempMap.end() ) (*k).second = 95.3; }

  22. Data Insertion to STL Containers == Copy • list::push_back(objA) map::insert(objB) • What actually saved in containers are copies, not original object • Thus, each insertion incurs an object copying procedure • If a data type is too complex, sometimes it is better to save the pointers to the objects

  23. empty() vs. size() == 0 • Two methods to check if a container is empty • empty(), takes constant time • Check if size() == 0, may take linear time!

  24. Container Adaptors • stack • stack< vector<T> > • stack< list<T> > • queue • queue< deque<T> > • priority_queue • priority_queue< vector<int>, less<int> >

  25. STL Algorithms • Many generic algorithms • for_each() • find() • count(), count_if() • copy(), swap(), replace(), remove(), merge() • sort(), nth_element() • min(), max() • partition() • … …

  26. Algorithm Example remove() #include<vector.h> #include<algorithm.h> … … vector<int> v; v.reserve(10); for ( int j = 1; j <= 10; j++ ) { v.push_back(j); } cout << v.size(); // print 10 v[3] = v[5] = v[9] = 99; remove( v.begin(), v.end(), 99 ); // remove all element == 99 cout << v.size(); // still print 10!

  27. The Myth of remove() At beginning 1 2 3 4 5 6 7 8 9 10 After change data 1 2 3 99 5 99 7 8 9 99 v.end() After remove() 1 2 3 5 7 8 9 8 9 99 remove() returns an iterator

  28. Make remove() More Meaningful #include<vector.h> #include<algorithm.h> … … vector<int> v; v.reserve(10); for ( int j = 1; j <= 10; j++ ) { v.push_back(j); } cout << v.size(); // print 10 v[3] = v[5] = v[9] = 99; v.erase( remove( v.begin(), v.end(), 99 ), v.end() ); cout << v.size(); // now print 7!

  29. What Else for STL? • Many other features • Internal implementation • Suggestion: • Buy an STL book • Use it as a dictionary

  30. Something About C++ • A nice book • Effective C++, Scott Meyers, Addison-Wesley, 1998

  31. class node { private: double rat; long x, y; double cap; long ID; node* parent; … … }; class node { private: long x, y, ID; double rat, cap; node* parent; … … }; // Put member variables of // same type together, this // improves memory efficiency Data Organization in Declaring Class

  32. class node { private: const int ID; long x, y; node* parent; }; node::node( int j, long a, long b) : ID(j), x(a), y(b) { } node::node( int j, long a, long b) : ID(j) { x = a; y = b; } Prefer Initialization to Assignment in Constructors • const or reference member variables have to be initialized • Initialization is always performed (to certain default value), even you do the assignment later • List members in an initialization list in the same order in which they are declared

  33. class node { … … long getID(); }; long node::getID() { return ID; } class node { … … inline long getID() { return ID; } }; Inline Function Inline function usually runs faster But, compiling time may be longer

  34. // This is file A.h, class typeB is // declared in file B.h #include <B.h> class typeA { … … typeB* memberB; inline void do() { memberB->doSome(); } }; // Change of A.h involves B.h // thus, compiling time is long // This is file A.h, class typeB is // declared in file B.h class typeB; class typeA { … … typeB* memberB; void do(); }; Minimize Compiling Dependencies

  35. class tree { … … node root; node getRoot(); }; // For a complex data type // return value takes time // on copying class node { … … node root; node& getRoot(); }; // Pass reference is faster // but, sometimes you have to // pass value Prefer Pass-by-Reference to Pass-by-Value

  36. Never Return Reference to Local Variable node& someClass::doSomething() { … … node localNode; … … return localNode; // This causes trouble! // Since the local variable is discarded // at the exit of the function }

More Related