Associative Containers Gordon College Prof Brinton 1 STL
Associative Containers Gordon College Prof. Brinton 1
STL - Assoc. Containers • Set – The key is the data set<int> int. Set; set<string> keyword; set<time 24> time. Set; To support the STL container - set; the programmer must overload the == operator and < operator by comparing the key field and giving a Boolean result. 2
STL - Assoc. Containers • Map – Stores entries as key-value pair. – In a pair, the first component is the key; the second is the value. Each component may have a different data type. map<int, record> student. File; student. File[2343554] = new student. File; student. File[2343554]. add. To. Balance(112); 3
Set and Map • Both containers do not allow duplicate keys. • Multiset and multimap (also STL containers) allow duplicate keys) 4
STL sets and maps 5
STL Set include <set> • Constructors: set(); set(T *first, T *last); default - empty set use pointers or iterators Examples: set<int> first; int myints[]= {10, 20, 30, 40, 50}; set<int> second (myints, myints+5); set<int> third (second); set<int> fourth (second. begin(), second. end()); // empty set of ints // pointers // a copy of second // iterators into second 6
STL Set include <set> • Operations: bool empty() const; void clear(); int size() const; int count(const T& key) const; //return either 1 or 0 iterator find(const T& key); const_iterator find(const T& key) const; // returns either an iterator or end() NOTE: STL Associative Containers iterators do access the elements in the defined order. 7
STL Set include <set> • Operations: pair<iterator, bool> insert(const T& key); // this return a pair object Example: string t[]={"this", "a", "test"}; set<string> s(t, t+4); pair<set<string>: : iterator, bool> result = s. insert("OK"); (result. second)? cout << "TRUE": cout << "FALSE"; Result: TRUEFALSE 8
STL Set include <set> • Operations: void erase ( iterator position ); void erase ( iterator first, iterator last ); size_type erase ( const key_type& x ); //returns either 1 or 0 void swap ( set<Key, Compare, Allocator>& st ); • Obtaining the bounds: pair<iterator, iterator> equal_range ( const key_type& x ) const; iterator lower_bound ( const key_type& x ) const; //iterator of first value not < x iterator upper_bound ( const key_type& x ) const; //iterator of first value > x 9
STL Set include <set> • Iterators: iterator begin(); const_iterator begin(const); iterator end(); const_iterator end(const); 10
Set operators • Union set. C = set. A + set. B; set. C = 1 2 3 4 5 6 7 8 11 15 • Intersection A*B set. C = set. A * set. B; set. C = 3 5 7 8 11 • Difference set. C = set. A - set. B; set. C = 1 4 8 1 5 8 3 11 4 7 6 5 3 15 11 2 7 11
Map include <map> • Operations are like set’s operations – – – – swap begin end size empty operator[] find erase //unlike set See the following examples 12
#include <string. h> #include <iostream> #include <map> using namespace std; int main() { map<int, string> Employees; Employees[5234] = "Mike C. "; Employees[3374] = "Charlie M. "; Employees[1923] = "David D. "; Employees[7582] = "John A. "; Employees[5328] = "Peter Q. "; cout << "Employees[3374]=" << Employees[3374] << endl; cout << "Map size: " << Employees. size() << endl; for( map<int, string>: : iterator ii=Employees. begin(); ii!=Employees. end(); ++ii) { cout << (*ii). first << ": " << (*ii). second << endl; } } 13
#include <string. h> #include <iostream> #include <map> using namespace std; int main() { map<int, string> Employees; Employees[5234] = "Mike C. "; Employees[3374] = "Charlie M. "; Employees[1923] = "David D. "; Employees[7582] = "John A. "; Employees[5328] = "Peter Q. "; Employees[3374]=Charlie M. Map size: 5 1923: David D. 3374: Charlie M. 5234: Mike C. 5328: Peter Q. 7582: John A. cout << "Employees[3374]=" << Employees[3374] << endl; cout << "Map size: " << Employees. size() << endl; for( map<int, string>: : iterator ii=Employees. begin(); ii!=Employees. end(); ++ii) { cout << (*ii). first << ": " << (*ii). second << endl; } } 14
#include <string. h> #include <iostream> #include <map> using namespace std; int main() { map<string, int> Employees; Employees["Mike C. "] = 5234; Employees["Charlie M. "] = 3374; Employees. insert(pair<string, int>("David D. ", 1923)); Employees. insert(map<string, int>: : value_type("John A. ", 7582)); Employees. insert(make_pair("Peter Q. ", 5328)); cout << "Map size: " << Employees. size() << endl; for( map<string, int>: : iterator ii=Employees. begin(); ii!=Employees. end(); ++ii) { cout << (*ii). first << ": " << (*ii). second << endl; } } 15
#include <string. h> #include <iostream> #include <map> using namespace std; Map size: 5 Charlie M. : 3374 David D. : 1923 John A. : 7582 Mike C. : 5234 Peter Q. : 5328 int main() { map<string, int> Employees; Employees["Mike C. "] = 5234; Employees["Charlie M. "] = 3374; Employees. insert(pair<string, int>("David D. ", 1923)); Employees. insert(map<string, int>: : value_type("John A. ", 7582)); Employees. insert(make_pair("Peter Q. ", 5328)); cout << "Map size: " << Employees. size() << endl; for( map<string, int>: : iterator ii=Employees. begin(); ii!=Employees. end(); ++ii) { cout << (*ii). first << ": " << (*ii). second << endl; } } 16
struct cmp_str { bool operator()(char const *a, char const *b) { return strcmp(a, b) < 0; } }; int main() { map<char *, int, cmp_str> Employees; Employees["Mike C. "] = 5234; Employees["Charlie M. "] = 3374; Employees. insert(pair<char *, int>("David D. ", 1923)); Employees. insert(map<char *, int>: : value_type("John A. ", 7582)); Employees. insert(make_pair((char *)"Peter Q. ", 5328)); cout << "Map size: " << Employees. size() << endl; for( map<char *, int, cmp_str>: : iterator ii=Employees. begin(); ii!=Employees. end(); ++ii) { cout << (*ii). first << ": " << (*ii). second << endl; } } 17
struct cmp_str { bool operator()(char const *a, char const *b) { return strcmp(a, b) < 0; } }; Map size: 5 Charlie M. : 3374 David D. : 1923 John A. : 7582 Mike C. : 5234 Peter Q. : 5328 int main() { map<char *, int, cmp_str> Employees; Could this be ordered Employees["Mike C. "] = 5234; differently? Employees["Charlie M. "] = 3374; Employees. insert(pair<char *, int>("David D. ", 1923)); Employees. insert(map<char *, int>: : value_type("John A. ", 7582)); Employees. insert(make_pair((char *)"Peter Q. ", 5328)); cout << "Map size: " << Employees. size() << endl; for( map<char *, int, cmp_str>: : iterator ii=Employees. begin(); ii!=Employees. end(); ++ii) { cout << (*ii). first << ": " << (*ii). second << endl; } } 18
Map details • Associative Arrays M[“Computer Science”] = 20; Keys are unique therefore: M[“Computer Science”] = 26; replaces the value in the tree for CS. 19
Map details • Creating a map: #include <map> int main() { map<string, double> A; … 20
Map Details • [ ] operator Steps 1. Search the for map for key 2. If key found, return a reference to the value object associated with key. 3. If key not found, create a new object of type value associated with key, and return a reference to that. 21
Map Details • [ ] operator int salary = Employee[“Jack Smith”]; Caution: this will create a new tree entry if it doesn’t exist and assign 0 to variable salary 22
Map Details • [ ] operator Better technique: if (( itr = Employee. find(“Jack Smith”)) == Employee. end()) cout << “ the employee does not exist. ” << endl; Else cout << “Employee Salary: “ << itr->second << endl; 23
Map Details • Pair Class 1. Contains two public members, first and second 2. Store key/value association itr->first itr->second 24
Map Details • Pair Class Easiest way to construct pair: pair<string, int> a; a = make_pair(string(“Jack Smith”), int(100000)); 25
Map Details • Element requirements: Each key and value must be assignable (an assignment operator which performs a “deep copy” Deep copy target of the assignment should be equal but independent of the source a = b; the value of a should match b - however if you change a it should not affect b (and vice versa) Note: if we talking about a linked list then a shallow copy would have two pointers pointing to the same list. 26
Map Details • Element requirements: Also each key should adhere to “weak ordering”: 1. A<A is false 2. Equality can be determined with (!(A<B) && !(B<A)) Note: only using the less than operator 3. If A<B and B<C then A<C must be true int, char, double, etc. (built-in types) are strict weak ordered 27
Map Details • Element requirements: value type used must have a defined default constructor. map <int, big. Number> The built in types have a type of default constructor: map<int, string> 28
Map Details Operation Description swap Swaps elements with another map. This operation is performed in constant time. Time Complexity O(1) Ex: map 1. swap(map 2); begin Returns an iterator to the first pair in the map. O(1) Ex: itr = map 1. begin(); end Returns an iterator just beyond the end of the map. O(1) 29
Map Details Operation Description size Returns the number of elements contained by the map. You should use empty() to test whether or not size equals 0, because empty() is faster. Time Complexity O(n) cout << map 1. size(); empty Returns true if the map contains zero elements. O(1) Operator [ ] Accepts a key and returns a reference to the object associated with key. Note that this operator always creates an element associated with key if it does not exist. O(log n) 30
Map Details Operation Description find Accepts a key and returns an iterator to the pair element if found. If the key is not found in the map, this method returns end(). Time Complexity O(log n) if ( (itr = map 1. find("Bob")) == map 1. end()) cerr << "Bob was not found in the map. " << endl; else cout << "Bob was found in the map. " << endl; 31
Map Details Operation Description erase There are three overloaded forms of this method. Time Complexity O(1) The first accepts a single iterator, and removes the element implied by the iterator from the map. The map should be non-empty. O(1). map 1. erase(map 1. begin()); // remove the first element 32
Map Details Operation Description erase There are three overloaded forms of this method. Time Complexity O(n) The second accepts two iterators, that specify a range of values within the map to be removed. The time complexity is logarithmic plus linear time for the length of the sequence being removed. The two iterators must be valid iterators within the sequence contained by the map. Formally, the range of values [starting, ending) are removed. At worst, this is an O(n) operation. Ex: map 1. erase(map 1. begin(), map 1. end()); // erase the entire map 33
Map Details Operation Description erase There are three overloaded forms of this method. Time Complexity O(log n) The last accepts an object of the key type, and removes all occurrences of the key from map. Note that since map elements all have unique keys, this will erase at most 1 element. O(log n). Ex: map 1. erase(string("Bob")); // removes all occurrences of "Bob" 34
Multimap/Multiset begin rbegin clear count equal_range insert find max_size operator= size swap end rend empty lower_bound erase upper_bound 35
Multimap/Multiset Details Operation Description constructor creates an empty multiset<int> S size returns the number of elements insert S. size() S. insert( const T& ) : adds an item to the set. If the item is already present, there will be multiple copies in the multiset/multimap S. insert(6); 36
Multimap/Multiset Details Operation Description count S. count( const T& t ) : returns the number of times that the item t is found in the set. This will be 0 if the item is not found erase S. erase( const T& t ) : removes the all items equal to t from the multiset. erase S. erase( multiset<T>: : iterator i ) : removes the item pointed to by i. S. erase( v ); // ALL: removes all of items == v from the multiset S. erase( S. find( v ) ); // ONE: removes the first item == v from the multiset 37
Multimap/Multiset Details Operation Description reverse( iterator begin, iterator end ) : reverses the order of the items: find S. find( const T& t ) : returns an iterator that points to the first item == t, or S. end() if the item could not be found. 38
Multimap/Multiset Details Operation Description equal_range S. equal_range(*iter) - returns a pair of iterators such that all occurrences of the item are in the iterator range pair<multiset <int>: : iterator, multiset <int>: : iterator > p; p = S. equal_range(5); 39
Multimap/Multiset Details equal_range multiset<int>: : iterator it; pair<multiset<int>: : iterator, multiset<int>: : iterator> ret; int myints[]= {77, 30, 16, 2, 30}; multiset<int> mymultiset (myints, myints+6); // 2 16 30 30 30 77 ret = mymultiset. equal_range(30); for (it=ret. first; it!=ret. second; ++it) ++(*it); // 2 16 31 31 31 77 40
Multimap/Multiset Details • How is multiset implemented? Multiset: BST - with integer value representing each occurrence of the element insert {find - if not present create node else increment count} erase {remove node and report back count} 12 (2) (5) 7 4 (2) 20 (1) 9 (3) 30 (1) HOW WOULD THESE BE HANDLED? clear empty count find size 41
Multimap/Multiset Details • How is multimap implemented? Multimap: BST - with list or map as the node’s payload insert {find - if not present create node else add value to list/set} erase {remove node and report back count} 12 (“Tom” -> “Jack” -> “Joe”) (“Tom”) 7 4 (“Jack” -> “Joe”) 20 (“Jack” -> “Joe”) 9 (“Jack”) 30 (“Emma”) HOW WOULD THESE BE HANDLED? clear empty count find size There is not guarantee as to order of duplicates 42
- Slides: 42