Maps are basically sets of key-value pairs, sorted and accessed by a "key" Called "associative containers" as they allow insert, access and removal based on these keys Multimaps are essentially multi sets of key-value pairs, sorted and accessed by a "key" Both structures store data as a key-value pair, unlike sequence containers that store data as a position-value Ordered by less, unless otherwise specified like this: map > myMap; The comparison (either less or greater in the examples above) must provide a weak ordering that matches the following assumptions: Antisymetric, i.e., if x < y then !(y < x) Transitive, i.e., if x < y and y < z then x < z Irreflexive (x myPair("CS140", 105); typedef map siMap; typedef siMap::value_type kvPair; typedef pair ibPair; siMap myMap; ibPair p; string name = "CS140"; p = myMap.insert(kvPair(name,139)); if (p.second) cout << "Inserted new pair"; else cout << "already had pair with key and value " << p.first->first << "and " << p.first->second; Useful map syntax ------------------ Map(); creates an empty map and is the default constructor Map (T *first T *last) creates a map containing keys from first to last * empty() and size() return if the map is empty and the number of elements, respectively * int count (const T& key) returns 1 if the key is in the map, 0 otherwise * iterator find(const T& key) returns an iterator pointing at the targeted element, or end() if it isn't found * pair insert (const T& item) If the key (item.first) is not in the map, insert and return a pair whose first element if an iterator pointing to the new element and true. Otherwise, return an iterator to the existing element and whose second element is false. On a successful insert, the size() of the map is increased, and if it was empty it is no longer * int erase(const T& key) If key is in the map, erase all items it is a part of and return the number of removals (more than 1 for a multi map). If the key is not found, return 0 * void erase(iterator element) Just like with sequence containers, if you provide an iterator to the new element it can be removed * void erase (iterator first_element, iterator last_element) Erase the elements in the range indicated by the two iterators * iterator begin() and iterator end() Just like sequence containers, provides the first and the item after the last via iterators * operator [] Provides "array-like" access by returning the value of the item with a specific key Can also be used in assignment like this: MyMap["CS140"]=105 the assignment operator when invoked like above either changes or adds an element, depending on whether it is in the map or not Sample #1 : map to count words in a file #include #include #include int main() { std::string s; std::map counters; // store each word and an associated counter // read the input, keeping track of each word and how often we see it while (std::cin >> s) ++counters[s]; // write the words and associated counts std::map::const_iterator it; for (it = counters.begin(); it != counters.end(); ++it) { std::cout << it->first << "\t" << it->second << std::endl; } return 0; Sample #2 : map to keep track of stock prices dow.insert (make_pair("APPL", 128.78); if (dow.find("T") != dow.end()) cout << "AT&T is in the Dow" << endl; typedef map::const_iterator Dow_iterator; for (Dow_iterator p = dow.begin(); p != dow.end(); ++p) const string& symbol = p->first; cout << p->second << dow_name[symbol] << endl Sample #3: doing cool things with functions double value_product(const pair &a, const pair&b) { return a.second * b.second; } double dj_index = inner_product (dow.begin(), dow.end(), dow_weight.begin, 0.0, plus(), value_product); takes all companies in the index (between begin() and end(), the weights, sets the initial value to 0.0, adds, and applies the value_product function to scale accordingly