Docstoc

Containers

Document Sample
Containers Powered By Docstoc
					CNS 3370
   Sequences
     vector,deque,list,(string),forward_list

   Container Adapters
     queue, stack, priority_queue

   Associative Containers
     set, unordered_set
     map, unordered_map
     plus multi_ versions of each of the above
bool empty();    // use instead of   size() == 0
size_t size();
void resize(size_t, T = T());
T& front();
T& back();                  // Not   forward_list
void push_back(const T&);   // Not   forward_list
void pop_back();            // Not   forward_list
// deque and list/forward_list only:
void push_front(const T&);
void pop_front();


//deque, vector and string only:
T& at(size_type n); // range-checked
T& operator[]
shrink_to_fit();
   Generalization of a pointer
   Overload at least operator!=,
                                operator==,
    operator*, operator++, operator->
   Some overload operator--,   operator[],
    pointer arithmetic
template<class Iterator, class T>
Iterator
find(Iterator start, Iterator past, const T& v)
{
    while (start != past)
    {
         if (*start == v)
             break;
         ++start;
    }
    return start;
}

  • All algorithms are implemented in terms of iterators
   Input
   Output
   Forward
   Bi-directional
   Random Access
   Modeled after file input
     Read-only access to elements
     Single-pass, forward traversal
   find expects an Input Iterator
     it only needs to read through the data once
template<class InputIterator, class T>
InputIterator
find(InputIterator start, InputIterator past,
      const T& v)
{
    while (start != past)
    {
         if (*start == v)
             break;
         ++start;
    }
    return start;
}
   Modeled after file output
     Write-only access to elements
     Single-pass, forward traversal
   Example: ostream_iterator:
    copy(a, a+n,
          ostream_iterator<int>(cout,“ “));
   Both read and write access
     can be used as Input or Output Iterators
   Multiple-pass, forward traversal
   unique expects a Forward Iterator
      list<T>::iterator p = unique(lst.first(),
                                   lst.end());

     It needs 2 simultaneous, read/write iterators
   Can do everything a Forward Iterator can
   Also support backwards traversal
     operator--()
     operator--(int)

   reverse requires a Bi-directional Iterator
list<T>::iterator p = lst.end();
while (p != lst.begin())
{
    --p;        // “advances” backwards

    // process *p
}
list<T>::reverse_iterator p = lst.rbegin();
while (p != lst.rend())
{
    // process *p, then:
    ++p;        // “advances” backwards
}
   Modeled after pointers
     support Pointer Arithmetic in constant time
     operator+, +=, -, -=, [], <, <=, >, >=

   sort expects a Random Access Iterator
“Functional” inheritance
via duck typing

(not via classes)
   Doesn’t provide a Random Access Iterator
     Generic sort will fail on a list
   Answer:
     Provides its own sort member function
   Also merge, remove, and unique
vector<int> v1;
…
// fill v1, then:
vector<int> v2;
copy(v1.begin(), v1.end(), v2.begin());
   Iterators work in overwrite mode by default
   Need an insert mode for cases like above
     that calls the appropriate insert operation
     provided by the container
   Replace output calls (operator*,
    operator=, etc.) with appropriate insert
    function
 back_insert_iterator
   calls push_back
 front_insert_iterator
   calls push_front
 insert_iterator
   calls insert
vector<int> v1;
…
// fill v1, then:
vector<int> v2;
copy(v1.begin(), v1.end(), back_inserter(v2));

(But there is still a better way)
   back_inserter
     creates a back_insert_iterator
   front_inserter
     creates a front_insert_iterator
   inserter
     creates an insert_iterator
   ostream_iterator
     an Output Iterator
       copy(v1.begin(), v1.end(),
             ostream_iterator<int>(cout, “ “));
   istream_iterator
     an Input Iterator
       copy(istream_iterator<int>(cin),
             istream_iterator<int>(),
             back_inserter(v1));
   insert, assign, erase, and constructors
   Usually more efficient than the generic
    algorithm counterparts
   Prefer over using copy
   See range-based.cpp
   For erasing selected elements of a sequence
     applies to vector, deque, string
     for lists, use remove/remove_if
   The idiom:
     The remove algorithm reorders the sequence,
      moving the deleted elements to the end
      ▪ returning an iterator to the first deleted element
     c.erase(remove(beg, end, x), end);
     c.erase(remove_if(beg, end, pred), end);
Higher-level Containers that use Sequences
   High-level abstract data types
     queue, stack, priority_queue
   They “adapt” sequences for specific uses
       i.e., they use a sequence for implementation
       stack & queue use deque by default
       priority_queue uses a vector
       can change the underlying sequence:
        stack<string, vector<string>> myStack;
   No iterators are provided
     they offer a more restricted interface
   queue:
     pushes at end, pops from front
     front, back, push, pop
   stack:
     pushes and pops at front
     top, push, pop
   priority_queue: (See pq.cpp, pq2.cpp)
     retrieves elements in priority order
     you provide a strict weak ordering
   priority_queue and ordered associative
    containers (set, map, multi_set, multi_map)
    require strict weak ordering comparators
     behave like less< >( ) ( (which calls operator<( ))
     never use <= or anything like it!!!
   Definition: f(x,y) is a SWO if:
     f(x,x) = false                (irreflexive)
     f(x,y) = !f(y,x)              (anti-symmetric)
     f(x,y) && f(y,z) => f(x,z)    (transitive)
   Two “flavors”
   Ordered
     tree-based storage
     O(log n) retrieval
     set, multi_set, map, multi_map
   Unordered
     hashed-based storage
     O(1) retrieval
     unordered_set, unordered_map
#include <iostream>
#include <set>
#include <string>
using namespace std;

int main()
{
    // Populate a set:
    set<string> s;
    s.insert("Alabama");
    s.insert("Georgia");
    s.insert("Tennessee");
    s.insert("Tennessee");
    // Print it out:
    auto p = s.begin();
    while (p != s.end())
        cout << *p++ << endl;
    cout << endl;

    // Do some searches:
    string key = "Alabama";
    p = s.find(key);
    cout << (p != s.end() ? "found " : "didn't find ")
         << key << endl;

    key = "Michigan";
    p = s.find(key);
    cout << (p != s.end() ? "found " : "didn't find ")
         << key << endl;
}
// Output:
Alabama
Georgia
Tennessee

found Alabama
didn't find Michigan
#include <iostream>
#include <map>
#include <string>
using namespace std;

int main()
{
    // Insert some elements (two ways):
    map<string,string,greater<string>> m;
    m.insert(make_pair(string("Alabama"),
                       string("Montgomery")));
    m["Georgia"] = "Atlanta";
    m["Tennessee"] = "Knoxville";
    m["Tennessee"] = "Nashville"; // overwrites
// Print   the map:
auto p =   m.begin();
while (p   != m.end()) {
    auto   elem = *p++;
    cout   << '{' << elem.first << ',’
           << elem.second << "}\n";
}
cout << endl;
    // Retrieve via a key:
    cout << '"' << m["Georgia"] << '"' << endl;
    cout << m.size() << endl;
    cout << '"' << m["Texas"] << '"' << endl;
    cout << m.size() << endl;
}

// Output:
{Tennessee,Nashville}
{Georgia,Atlanta}
{Alabama,Montgomery}

"Atlanta"
3
""
4
   Shows the conciseness of map’s design
   Count the number of each word in a text file
   wordcount.cpp
     output in wordcount-gettysburg.out
   Necessary to maintain proper order in the
    underlying tree data structure
   They test for equivalence, not equality, to
    maintain uniqueness
   x and y are equivalent iff !cmp(x,y) && !cmp(y,x)
     i.e., neither precedes the other
   Example:
     swo.cpp
     ignores non-alpha characters in strings

				
DOCUMENT INFO
Shared By:
Categories:
Tags:
Stats:
views:18
posted:8/2/2011
language:English
pages:40