Download presentation
Presentation is loading. Please wait.
Published byBennett Cunningham Modified over 9 years ago
1
CNS 3370
2
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
4
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
5
// 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();
6
Generalization of a pointer Overload at least operator!=, operator==, operator*, operator++, operator-> Some overload operator--, operator[], pointer arithmetic
7
template 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
8
Input Output Forward Bi-directional Random Access
9
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
10
template InputIterator find(InputIterator start, InputIterator past, const T& v) { while (start != past) { if (*start == v) break; ++start; } return start; }
11
Modeled after file output Write-only access to elements Single-pass, forward traversal Example: ostream_iterator: copy(a, a+n, ostream_iterator (cout,“ “));
12
Both read and write access can be used as Input or Output Iterators Multiple-pass, forward traversal unique expects a Forward Iterator list ::iterator p = unique(lst.first(), lst.end()); It needs 2 simultaneous, read/write iterators
13
Can do everything a Forward Iterator can Also support backwards traversal operator--() operator--(int) reverse requires a Bi-directional Iterator
14
list ::iterator p = lst.end(); while (p != lst.begin()) { --p;// “advances” backwards // process *p }
15
list ::reverse_iterator p = lst.rbegin(); while (p != lst.rend()) { // process *p, then: ++p;// “advances” backwards }
16
Modeled after pointers support Pointer Arithmetic in constant time operator+, +=, -, -=, [],, >= sort expects a Random Access Iterator
17
“Functional” inheritance via duck typing (not via classes)
18
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
19
vector v1; … // fill v1, then: vector v2; copy(v1.begin(), v1.end(), v2.begin());
20
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
21
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
22
vector v1; … // fill v1, then: vector v2; copy(v1.begin(), v1.end(), back_inserter(v2)); (But there is still a better way)
23
back_inserter creates a back_insert_iterator front_inserter creates a front_insert_iterator inserter creates an insert_iterator
24
ostream_iterator an Output Iterator copy(v1.begin(), v1.end(), ostream_iterator (cout, “ “)); istream_iterator an Input Iterator copy(istream_iterator (cin), istream_iterator (), back_inserter(v1));
25
insert, assign, erase, and constructors Usually more efficient than the generic algorithm counterparts Prefer over using copy See range-based.cpp
26
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);
27
Higher-level Containers that use Sequences
28
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 > myStack; No iterators are provided they offer a more restricted interface
29
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
30
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)
32
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
33
#include using namespace std; int main() { // Populate a set: set s; s.insert("Alabama"); s.insert("Georgia"); s.insert("Tennessee");
34
// 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; }
35
// Output: Alabama Georgia Tennessee found Alabama didn't find Michigan
36
#include using namespace std; int main() { // Insert some elements (two ways): map > m; m.insert(make_pair(string("Alabama"), string("Montgomery"))); m["Georgia"] = "Atlanta"; m["Tennessee"] = "Knoxville"; m["Tennessee"] = "Nashville"; // overwrites
37
// Print the map: auto p = m.begin(); while (p != m.end()) { auto elem = *p++; cout << '{' << elem.first << ',’ << elem.second << "}\n"; } cout << endl;
38
// 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
39
Shows the conciseness of map’s design Count the number of each word in a text file wordcount.cpp output in wordcount-gettysburg.out
40
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
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.