Associative containers (C++)


In C++, associative containers or associative collections are a group of class templates in the standard library that implement ordered associative arrays. Being templates, they can be used to store arbitrary elements, such as integers or custom classes. Like all other standard library components, they reside in namespace std.
The following containers are defined in the current revision of the C++ standard: std::set, std::map, std::multiset, std::multimap
Each of these containers differ only on constraints placed on their elements.
There are also versions of these collections in namespace std::pmr. These versions specify the optional template parameter Allocator as std::pmr::polymorphic_allocator.
std::set and std::multiset are declared in header , while std::map and std::multimap are declared in header .
The associative containers are similar to the unordered associative containers in C++ standard library, the only difference is that the unordered associative containers, as their name implies, do not order their elements.
std::map and std::set are usually implemented as red-black trees, and are essentially equivalent to java.util.TreeMap and java.util.TreeSet from Java or std::collections::BTreeMap and std::collections::BTreeSet from Rust.

Design

Characteristics

Key uniqueness: in map and set each key must be unique. multimap and multiset do not have this restriction.Element composition: in map and multimap each element is composed from a key and a mapped value. In set and multiset each element is key; there are no mapped values.Element ordering: elements follow a strict weak ordering
Associative containers are designed to be especially efficient in accessing its elements by their key, as opposed to sequence containers which are more efficient in accessing elements by their position. Associative containers are guaranteed to perform operations of insertion, deletion, and testing whether an element is in it, in logarithmic time – As such, they are typically implemented using self-balancing binary search trees and support bidirectional iteration. Iterators and references are not invalidated by insert and erase operations, except for iterators and references to erased elements.The defining characteristic of associative containers is that elements are inserted in a pre-defined order, such as sorted ascending.
The associative containers can be grouped into two subsets: maps and sets. A map, sometimes referred to as a dictionary, consists of a key/value pair. The key is used to order the sequence, and the value is somehow associated with that key. For example, a map might contain keys representing every unique word in a text and values representing the number of times that word appears in the text. A set is simply an ascending container of unique elements.
As stated earlier, map and set only allow one instance of a key or element to be inserted into the container. If multiple instances of elements are required, use multimap or multiset.
Both maps and sets support bidirectional iterators. For more information on iterators, see Iterators.
While not officially part of the STL standard, hash_map and hash_set are commonly used to improve searching times. These containers store their elements as a hash table, with each table entry containing a bidirectional linked list of elements. To ensure the fastest search times, make sure that the hashing algorithm for your elements returns evenly distributed hash values.

Performance

The asymptotic complexity of the operations that can be applied to associative containers are as follows:
OperationComplexity
Searching for an element
Inserting a new element
Incrementing/decrementing an iterator
Removing a single element

Unordered sets are usually more efficient than ordered sets, with inserting, removing, and searching operations being done in time.

Overview of functions

The containers are defined in headers named after the names of the containers, e.g. set is defined in header . All containers satisfy the requirements of the concept, which means they have begin, end, size, max_size, empty, and swap methods.
setmapmultisetmultimapDescription
Constructs the container from variety of sources
Destructs the set and the contained elements
Assigns values to the container
Returns the allocator used to allocate memory for the elements
Element accessAccesses specified element with bounds checking.
Element access]Accesses specified element without bounds checking.
IteratorsReturns an iterator to the beginning of the container
IteratorsReturns an iterator to the end of the container
IteratorsReturns a reverse iterator to the reverse beginning of the container
IteratorsReturns a reverse iterator to the reverse end of the container
CapacityChecks whether the container is empty
CapacityReturns number of elements in the container.
CapacityReturns the maximum possible number of elements in the container
ModifiersClears the contents.
ModifiersInserts elements.
ModifiersConstructs elements in-place
ModifiersConstructs elements in-place using a hint
ModifiersErases elements.
ModifiersSwaps the contents with another container.
LookupReturns the number of elements matching specific key.
LookupFinds an element with specific key.
LookupReturns a range of elements matching specific key.
LookupReturns an iterator to the first element with a key not less than the given value.
LookupReturns an iterator to the first element with a key greater than a certain value.
ObserversReturns the key comparison function.
ObserversReturns the value comparison function. In set and multiset this function is equivalent to key_comp, since the elements are composed from a key only.

Usage

The following code demonstrates how to use the map to count occurrences of words. It uses the word as the key and the count as the value.

import std;
using std::cin;
using std::map;
using std::string;
int main

When executed, program lets user type a series of words separated by spaces, and a word "end" to signify the end of input. Then user can input a word to query how many times it has occurred in the previously entered series.
The above example also demonstrates that the operator inserts new objects in the map if there is not one associated with the key. So integral types are zero-initialized, strings are initialized to empty strings, etc.
The following example illustrates inserting elements into a map using the insert function and searching for a key using a map iterator and the find function:

import std;
using CharIntTreeMap = std::map;
using std::cin;
using std::pair;
int main

Example shown above demonstrates the usage of some of the functions provided by map, such as insert, erase, find, etc.
When program is executed, six elements are inserted using the insert function, then the first element is deleted using erase function and the size of the map is outputted. Next, the user is prompted for a key to search for in the map. Using the iterator created earlier, the find function searches for an element with the given key. If it finds the key, the program prints the element's value. If it doesn't find it, an iterator to the end of the map is returned and it outputs that the key could not be found. Finally all the elements in the tree are erased using clear.

Iterators

Maps may use iterators to point to specific elements in the container. An iterator can access both the key and the mapped value of an element:

// Declares a map iterator
std::map::iterator it;
// Accesses the Key value
it->first;
// Accesses the mapped value
it->second;
// The "value" of the iterator, which is of type std::pair
;

Below is an example of looping through a map to display all keys and values using iterators:

import std;
using std::map;
using std::string;
int main