1 / 24

Standard Template Library (STL) Containers

Standard Template Library (STL) Containers. Moshe Fresko Bar-Ilan University Object Oriented Programming 2006-2007. Standard Library Design. The C++ Standard Library Provides support for language features such as memory management and run-time type information

tovi
Télécharger la présentation

Standard Template Library (STL) Containers

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. Standard Template Library (STL) Containers Moshe Fresko Bar-Ilan University Object Oriented Programming 2006-2007

  2. Standard Library Design The C++ Standard Library • Provides support for language features such as memory management and run-time type information • Supplies information about implementation-defined aspects of the language, such as the largest float value • Supplies functions that cannot be implemented optimally in the language itself for every system, such as sqrt() and memmove() • Supplies non-primitive facilities that a programmer can rely on for portability, such as lists, maps, sort functions, and I/O streams • Provides a framework for extending the facilities • Provides the common foundation for other libraries

  3. Containers • Container is an object that holds other objects • Examples: lists, vectors, and associative arrays • Objects can be added and removed from a container • STL defines two kinds of containers • Sequences • Associative Containers

  4. Containers <vector> one-dimensional array of T <list> doubly-linked list of T <deque> double-ended queue of T <queue> queue of T (priority_queue is defined here) <stack> stack of T <map> associative array from T to Value (multimap is defined here) <set> set of T (multiset is defined here) <bitset> array of booleans

  5. vector • Vectors are dynamic containers that keep sequence of elements of a template type T. • The standard vector is a template defined in namespace std and presented in <vector>. • It first defines a set of types template <class T, class A=allocator<T> > class std::vector { public: typedef T value_type; // type of element typedef A allocator_type; // type of mem.mngr. typedef typename A::size_type size_type; typedef typename A::difference_type difference_type; typedef ……… iterator; // T* typedef ……… const_iterator; // const T* typedef std::reverse_iterator<iterator> reverse_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator; typedef typename A::pointer pointer; typedef typename A::const_pointer const_pointer; typedef typename A::reference reference; typedef typename A::const_reference const_reference; //……… };

  6. vector types usage Example template<class C> typename C::value_type sum(const C& c) { typename C::value_type s=0; typename C::const_iterator p=c.begin(); while (p!=c.end()) { s+=*p; ++p; } return s; } // Usage of that function int main() { vector<int>& vi; vector<float>& vf; vector<Complex>& vc; // ......... int isum = sum(vi); float fsum = sum(vf); Complex csum = sum(vc); }

  7. iterators • Iterators are used to navigate containers without the programmers having to know the actual type used to identify the elements. template <class T, class A=allocator<T> > class std::vector { public: // ……… iterator begin(); // points to 1st element const_iterator begin() const; iterator end(); // points to one-past-last element const_iterator end() const; reverse_iterator rbegin(); // 1st element of reverse seq. const_reverse_iterator rbegin() const; reverse_iterator rend(); // one-past-last element of reverse seq. const_reverse_iterator rend() const; // ……… }; • begin()/end() works in ordinary element order • rbegin()/rend() works in reverse element order • In a list of three elements A, B, C begin() end() A B C rend() rbegin()

  8. iterators • To keep track of a list of Complex numbers … vector<Complex> vec ; vec.push_back(Complex(3,4)) ; vec.push_back(Complex(5.0,6.6)) ; vec.push_back(Complex(-3.1,5.2)) ; … vector<Complex>::iterator it; for(it=vec.begin();it!=vec.end();++it) { Complex c = *it ; cout<<“The next Complex number in list is:”<<c<<endl; } for(vector<Complex>::reverse_iterator rit=vec.rbegin(); rit!=rend();++rit) cout<<“Reverse order next Complex number:”<<*rit<<endl; …

  9. iterators • Example: A utility that searches for the last occurrence of an element in a sequence template<class C> typename C::iterator find_last(C& c, typename C::value_type v) { typename C::reverse_iterator p=c.rbegin(); while (p!=c.rend()) { if (*p==v) { typename C::iterator i=p.base(); return --i; } ++p; } return c.end(); }

  10. Element Access • In vector container types one can easily and efficiently access individual elements in any order. template <class T, class A=allocator<T> > class std::vector { public: // ……… reference operator[](size_type n); // unchecked access const_reference operator[](size_type n) const; reference at(size_type n); // checked access const_reference at(size_type n) const; reference front(); // first element const_reference front() const; reference back(); // last element const_reference back() const; // ……… };

  11. Element Access • operator[]() provides unchecked access whereas at() does a range check and may throw out_of_range.void f(vector<int>& vi, int i1, int i2) { for (int i=0;i<vi.size();++i) { int next=v[i]; // … } try { v.at(i1)=v.at(i2); // range check is done } catch(out_of_range) { // … } } • The return values are reference or const_reference depending on the container object being const or not. • For vector<X>, reference is simply X& and const_reference is const X&. vector<int> vi(1); vi[0]=10; int& i=vi[0]; i=20; // same as v[i]=20 • The effect of trying to create an out_of_range reference is undefined. • front() returns the element pointed by begin().

  12. Constructors, Destructors, Copy operators template <class T, class A=allocator<T> > class std::vector { public: // ……… explicit vector(const A& =A()); explicit vector(size_type n, const T& val=T(), const A&=A()); template <class In> // In must be an input iterator vector(In first,In last,const A&=A());// copy from [first:last[ vector(const vector& x); ~vector(); vector& operator=(const vector& x); template <class In> void assign(In first, In last);// In must be an input iterator void assign(size_type n, const T& val); // ……… };

  13. Examples for Ctor, Dtor vector<Record> vr(10000); void f(int s1, int s2) { vector<int> vi(s1); vector<double>* p=new vector<double>(s2); } class Num { public: Num(long); } vector<Num> v1(1000); // Error. No default ctor vector<Num> v2(1000,Num(0)); // ok void f(const list<X>& lst) { vector<X> vl(lst.begin(),lst.end()); char p[]=“Something”; vector<char> v2(p,&p[sizeof(p)-1]); }

  14. Stack operations template <class T, class A=allocator<T> > class std::vector { public: // ……… void push_back(const T& x); // add to end void pop_back(); // remove last element // ……… }; • Example void f(vector<char>& s) { s.push_back(‘a’); s.push_back(‘b’); s.push_back(‘c’); s.pop_back(); // s.back()==‘b’ s.pop_back(); // s[s.size()-1]==‘a’ }

  15. List Operations • To add/remove elements to/from the middle of the vector template <class T, class A=allocator<T> > class std::vector { public: // ……… iterator insert(iterator pos, const T& x); void insert(iterator pos,size_type n, const T& ); template <class In> void insert(iterator pos, In first, In last); iterator erase(iterator pos); iterator erase(iterator first, iterator last); // ……… };

  16. Example List Operations • Examples vector<string> fruit; fruit.push_back(“peach”); fruit.push_back(“apple”); fruit.push_back(“kiwi”); fruit.push_back(“pear”); fruit.push_back(“starfruit”); fruit.push_back(“grape”); sort(fruit.begin(),fruit.end()); vector<string>::iterator p1=find_if(fruit.begin(),fruit.end(),initial(‘p’)); vector<string>::iterator p2=find_if(p1,fruit.end(),initial_not(‘p’)); fruit.erase(p1,p2); // deletes those starting with ‘p’ fruit.erase(find(fruit.begin(),fruit.end(),”starfruit”)); fruit.erase(fruit.begin()+1); fruit.insert(fruit.begin()+1,”cherry”); fruit.insert(fruit.end(),”orange”);

  17. Size and Capacity • A vector grows as needed and sometimes it is worthwhile to affect its growth. template <class T, class A=allocator<T> > class std::vector { public: // ……… size_type size() const(); // number of elements bool empty() const {return size()==0;} size_type max_size() const; // size of largest vec void resize(size_type sz, T val=T()); size_type capacity() const;// size of mem void reserve(size_type n); // reserve mem // ……… };

  18. Size and Capacity - Example class Histogram { vector<int> count; public: Histogram(int h) : count(max(h,8)) { } void record(int i) { if (i<0) i=0; if (count.size()<=i) count.resize(i+1); count[i]++; } }; void addNNumbers(vector<int>& vi, int n) { vi.clear(); vi.reserve(n); for (int i=0;i<n;++i) vi.push_back(i); }

  19. Other member functions template <class T, class A=allocator<T> > class std::vector { public: // ……… void swap(vector&); allocator_type get_allocator()const; // ……… }; template <class T, class A> bool std::operator==(const vector<T,A>& x, const vector<T,A>& y); bool std::operator<(const vector<T,A>& x, const vector<T,A>& y); // Example: for giving memory back to system vector<X> v; //… // many operations on v // { vector<X> tmp=v; v.swap(tmp); }

  20. Exercises • Create a vector containing the letters of alphabet in order. Print them in reverse order. • Create a string vector. Read from the user strings and insert to it. Sort and print the sorted list. • Create a two dimensional string vector. Read names from the user and insert it into a vector according to its initial character. ‘A’ will be inserted into the 65th vector, ‘B’ into 66th, etc. • Write a class Student containing name, idnumber, and grade. Create a vector of students and fill it. Sort them. How can you find a student and change his grade?

  21. List • List keeps a sequence of elements like vector. But it is optimized for insertion and deletion. • It is implemented by doubly-linked list. template <class T, class A=allocator<T> class std::list { public: // types and operations like vector // except [], at(), capacity(), reserve() // … };

  22. Splice, sort, merge • List has some operations suited for doubly linked lists. template <class T, class A=allocator<T> class std::list { public: void splice(iterator pos, list&x); // move all elements from x to pos void splice(iterator pos, list& x, iterator p); // move only *p from x void splice(iterator pos, list& x, iterator first, iterator last); void merge(list&); template <class Cmp> void merge(list&,Cmp); void sort(); template <class Cmp> void sort(Cmp); // … };

  23. Comparisons • Associative containers require that the key elements can be ordered. • Some container operations (like sort, merge, binary_search) require ordering. • Default ordering is done according to operator<. • If an ordering criteria is cmp • cmp(x,x) is false • If cmp(x,y) and cmp(y,z) then cmp(x,z) • Define equiv(x,y) as !(cmp(x,y)||cmp(y,x)If equiv(x,y) and equiv(y,z) then equiv(x,z)

  24. Comparisons - example • Consider template <class R> void sort(R first, R last); template <class R, class Cmp> void sort(R first, R last, Cmp cmp); • For sorting a string list case-insensitive class NoCase { public: bool operator()(const string&x,const string&y) const { string::const_iterator p=x.begin(),q=y.begin(); while (p!=x.end() && q!=y.end() && toupper(*p)==toupper(*q)) { ++p; ++q; } if (p==x.end()) return q!=y.end(); return toupper(*p)<toupper(*q); } }; • Usage sort(fruit.begin(),fruit.end(),NoCase());

More Related