400 likes | 422 Views
Dive into the world of Associative Containers in C++ with this comprehensive guide covering Sets and Maps in the STL library. Learn constructors, operations, and essential functions for efficient data handling. Master Set unions, intersections, and differences.
E N D
Associative Containers Gordon College Prof. Brinton
STL - Assoc. Containers • Set • The key is the data set<int> intSet; set<string> keyword; set<time24> timeSet; To support the STL container - set; the programmer must overload the == operator and < operator by comparing the key field and giving a Boolean result.
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> studentFile; studentFile[2343554] = new studentFile; studentFile[2343554].addToBalance(112);
Set and Map • Both containers do not allow duplicate keys. • Multiset and multimap (also STL containers) allow duplicate keys)
set(); Create an empty set. This is the Default Constructor. CLASS set CLASS set <set> <set> Constructors Operations set(T *first, T *last); Initialize the set by using the address range [first, last). bool empty() const; Is the set empty? int size() const; Return the number of elements in the set.
int count(const T& key) const; Search for key in the set and return 1 if it is in the set and 0 otherwise. CLASS set <set> Operations iterator find(const T& key); Search for key in the set and return an iterator pointing at it, or end() if it is not found. Const_iterator find(const T& key) const; Constant version.
CLASS set <set> Operations pair<iterator, bool> insert(const T& key); If key is not in the set, insert it and then return a pair whose first element is an iterator pointing to the new element and whose second element is true. Otherwise, return a pair whose first element is an iterator pointing at the existing element and whose second element is false. Postcondition: The set size increases by 1 if key is not in the set. int erase(const T& key); If key is in the set, erase it and return 1; otherwise, return 0. Postcondition: The set size decreases by 1 if key is in the set.
CLASS set <set> Operations void erase(iterator pos); Erase the item pointed to by pos. Preconditions: The set is not empty, and pos points to a valid set element. Postcondition: The set size decreases by 1. void erase(iterator first, iterator last); Erase the elements in the range [first, last). Precondition: The set is not empty. Postcondition: The set size decreases by the number of elements in the range.
CLASS set <set> Operations iterator begin(); Return an iterator pointing at the first member in the set. const_iterator begin(const); Constant version of begin(). iterator end(); Return an iterator pointing just past the last member in the set. const_iterator end() const; Constant version of end().
Set operations 3 8 11 15 2 1 4 6 • Union setC = setA + setB; setC = 1 2 3 4 5 6 7 8 11 15 • Intersection A*B setC = setA * setB; setC = 1 3 5 7 8 11 • Difference setC = setA - setB; setC = 1 4 3 8 11 7 5 7 5
Map • swap • begin • end • size • empty • operator[] • find • erase
#include <string.h> #include <iostream> #include <map> #include <utility> 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 << 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; } }
Employees[3374]=Charlie M. Map size: 5 1923: David D. 3374: Charlie M. 5234: Mike C. 5328: Peter Q. 7582: John A. #include <string.h> #include <iostream> #include <map> #include <utility> 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 << 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; } }
#include <string.h> #include <iostream> #include <map> #include <utility> using namespace std; int main() { map<string, int> Employees; Employees["Mike C."] = 5234; Employees["Charlie M."] = 3374; Employees.insert(std::pair<string,int>("David D.",1923)); Employees.insert(map<string,int>::value_type("John A.",7582)); Employees.insert(std::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; } }
Map size: 5 Charlie M.: 3374 David D.: 1923 John A.: 7582 Mike C.: 5234 Peter Q.: 5328 #include <string.h> #include <iostream> #include <map> #include <utility> using namespace std; int main() { map<string, int> Employees; Employees["Mike C."] = 5234; Employees["Charlie M."] = 3374; Employees.insert(std::pair<string,int>("David D.",1923)); Employees.insert(map<string,int>::value_type("John A.",7582)); Employees.insert(std::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; } }
struct cmp_str { bool operator()(char const *a, char const *b) { return std::strcmp(a, b) < 0; } }; int main() { map<char *, int, cmp_str> Employees; Employees["Mike C."] = 5234; Employees["Charlie M."] = 3374; Employees.insert(std::pair<char *,int>("David D.",1923)); Employees.insert(map<char *,int>::value_type("John A.",7582)); Employees.insert(std::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; } }
Map size: 5 Charlie M.: 3374 David D.: 1923 John A.: 7582 Mike C.: 5234 Peter Q.: 5328 struct cmp_str { bool operator()(char const *a, char const *b) { return std::strcmp(a, b) < 0; } }; int main() { map<char *, int, cmp_str> Employees; Employees["Mike C."] = 5234; Employees["Charlie M."] = 3374; Employees.insert(std::pair<char *,int>("David D.",1923)); Employees.insert(map<char *,int>::value_type("John A.",7582)); Employees.insert(std::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; } }
Map details • Associative Arrays M[“Computer Science”] = 20; Keys are unique therefore: M[“Computer Science”] = 26; replaces the value in the tree for CS.
Map details • Creating a map: #include <map> int main() { map<string, double> A; …
Map Details • [ ] operator Steps • Search the for map for key • If key found, return a reference to the value object associated with key. • If key not found, create a new object of type value associated with key, and return a reference to that.
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
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;
Map Details • Pair Class 1. Must include <utility> 2. Contains two public members, first and second 3. Store key/value association itr->first itr->second
Map Details • Pair Class Easiest way to construct pair: pair<string, int> a; a = make_pair(string(“Jack Smith”), int(100000));
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.
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
Map Details • Element requirements: value type used must have a defined default constructor. map <int, bigNumber> The built in types have a type of default constructor: map<int, string>
Multiset Allow multiple items with same key