Containers and Iterators

40
CNS 3370

description

CNS 3370. Containers and Iterators. Standard Containers. 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. Sequences. - PowerPoint PPT Presentation

Transcript of Containers and Iterators

Page 1: Containers and Iterators

CNS 3370

Page 2: Containers and Iterators

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

Page 3: Containers and Iterators
Page 4: Containers and Iterators

bool empty(); // use instead of size() == 0size_t size();void resize(size_t, T = T()); T& front(); T& back(); // Not forward_listvoid push_back(const T&); // Not forward_listvoid pop_back(); // Not forward_list

Page 5: Containers and Iterators

// 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-checkedT& operator[]shrink_to_fit();

Page 6: Containers and Iterators

Generalization of a pointerOverload at least operator!=, operator==, operator*, operator++, operator->

Some overload operator--, operator[],

pointer arithmetic

Page 7: Containers and Iterators

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

Page 8: Containers and Iterators

InputOutputForwardBi-directionalRandom Access

Page 9: Containers and Iterators

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

Page 10: Containers and Iterators

template<class InputIterator, class T>InputIterator find(InputIterator start, InputIterator past, const T& v){ while (start != past) { if (*start == v) break; ++start; } return start;}

Page 11: Containers and Iterators

Modeled after file output Write-only access to elements

Single-pass, forward traversalExample: ostream_iterator:copy(a, a+n,

ostream_iterator<int>(cout,“ “));

Page 12: Containers and Iterators

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

Page 13: Containers and Iterators

Can do everything a Forward Iterator can

Also support backwards traversal operator--()

operator--(int)

reverse requires a Bi-directional Iterator

Page 14: Containers and Iterators

list<T>::iterator p = lst.end();while (p != lst.begin()){ --p; // “advances” backwards

// process *p}

Page 15: Containers and Iterators

list<T>::reverse_iterator p = lst.rbegin();while (p != lst.rend()){ // process *p, then: ++p; // “advances” backwards}

Page 16: Containers and Iterators

Modeled after pointers support Pointer Arithmetic in constant

time operator+, +=, -, -=, [], <, <=, >, >=

sort expects a Random Access Iterator

Page 17: Containers and Iterators

“Functional” inheritance via duck typing

(not via classes)

Page 18: Containers and Iterators

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

Page 19: Containers and Iterators

vector<int> v1;…// fill v1, then:vector<int> v2;copy(v1.begin(), v1.end(), v2.begin());

Page 20: Containers and Iterators

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

Page 21: Containers and Iterators

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

Page 22: Containers and Iterators

vector<int> v1;…// fill v1, then:vector<int> v2;copy(v1.begin(), v1.end(), back_inserter(v2));

(But there is still a better way)

Page 23: Containers and Iterators

back_inserter

creates a back_insert_iterator front_inserter

creates a front_insert_iterator inserter

creates an insert_iterator

Page 24: Containers and Iterators

ostream_iterator an Output Iterator copy(v1.begin(), v1.end(),

ostream_iterator<int>(cout, “ “)); istream_iterator

an Input Iteratorcopy(istream_iterator<int>(cin),

istream_iterator<int>(),

back_inserter(v1));

Page 25: Containers and Iterators

insert, assign, erase, and constructors

Usually more efficient than the generic algorithm counterparts

Prefer over using copySee range-based.cpp

Page 26: Containers and Iterators

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);

Page 27: Containers and Iterators

Higher-level Containers that use Sequences

Page 28: Containers and Iterators

High-level abstract data types queue, stack, priority_queue

They “adapt” sequences for specific uses i.e., they use a sequence for implementationstack & queue use deque by defaultpriority_queue uses a vectorcan change the underlying sequence:stack<string, vector<string>> myStack;

No iterators are provided they offer a more restricted interface

Page 29: Containers and Iterators

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

Page 30: Containers and Iterators

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)

Page 31: Containers and Iterators
Page 32: Containers and Iterators

Two “flavors”Ordered

tree-based storage O(log n) retrievalset, multi_set, map, multi_map

Unorderedhashed-based storageO(1) retrievalunordered_set, unordered_map

Page 33: Containers and Iterators

#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");

Page 34: Containers and Iterators

// 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;}

Page 35: Containers and Iterators

// Output:AlabamaGeorgiaTennessee

found Alabamadidn't find Michigan

Page 36: Containers and Iterators

#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

Page 37: Containers and Iterators

// Print the map: auto p = m.begin(); while (p != m.end()) { auto elem = *p++; cout << '{' << elem.first << ',’ << elem.second << "}\n"; } cout << endl;

Page 38: Containers and Iterators

// 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

Page 39: Containers and Iterators

Shows the conciseness of map’s design

Count the number of each word in a text file

wordcount.cpp output in wordcount-gettysburg.out

Page 40: Containers and Iterators

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