Open-Source Internship opportunity by OpenGenus for programmers. Apply now.
Multimaps in C++ STL are similar to maps in C++. The only difference is that maps cannot contain duplicate keys, whereas multimaps can contain multiple similar keys. It is a container that holds key-value pairs (like maps), and allows multiple entries with the same key.
Syntax for multimap :
template < class Key, //multimap::key_type
class T, //multimap::mapped_type
class Compare = less<Key>, //multimap::key_compare
class Alloc = allocator<pair<const Key, T> > //multimap::allocator_tpe
> class multimap;
The different ways to initialize multimaps are:
- Method 1: Inserting using make_pair
- Method 2 : Using pair
- Method 3 : Using pair
- Method 4 :Initializing with initializer list
- Method 5 : Constructing a multimap n from another multimap m
- Method 6 : Using copy constructor
- Method 7 : Using emplace_hint()
Some points about multimaps
- Multimap is an associative container that holds a sorted list of key-value pairs, regardless of the order of insertion into the multimap
- It permits multiple entries with the same key
- It stores the key in sorted order (we can choose the order : ascending or descending, using the third parameter) :
Syntax :
std::multimap<T1, T2, std::greater<>> obj;
- We do not have at() and [] operators in multimap which we have in map
- By default it uses the < operator to compare the keys
- The key and its value in a multimap are always inserted together, as a pair, that is, you cannot insert only the key or only the value into the multimap (double or nothing). The key and value are considered as a single entry into the multimap.
In this article, we explore different ways to initialize multimaps in C++ Standard Template Library
Multimap initializations in C++
Let's get started !
Consider inserting the following key-value pairs :
(a,1) , (a,1), (b,2), (c,3), (a,2), (d,4)
Most commonly used way to initialize a multimap :
Here, we use the insert() function and insert the the entries (key and value) using { } (curly braces). Here, we insert each entry one-by-one. In fact, in the first 3 Methods below also we insert each entry of the multimap one-by-one.
std::multimap<char, int> m; //empty multimap container
m.insert({'a',1}); //inserting (a,1)
m.insert({'a',1}); //inserting (a,1)
m.insert({'b',2}); //inserting (b,2)
m.insert({'c',3}); //inserting (c,3)
m.insert({'a',2}); //inserting (a,2)
m.insert({'d',4}); //inserting (d,4)
Method 1: Inserting using make_pair
make_pair constructs a pair object and we insert that object into our multimap. While using make_pair you need not mention the types of key and value, every time you insert an entry.
Empty Container Constructor :
std::multimap<char, int> m; //empty multimap container
m.insert(make_pair('a',1)); //inserting (a,1)
m.insert(make_pair('a',1)); //inserting (a,1)
m.insert(make_pair('b',2)); //inserting (b,2)
m.insert(make_pair('c',3)); //inserting (c,3)
m.insert(make_pair('a',2)); //inserting (a,2)
m.insert(make_pair('d',4)); //inserting (d,4)
Output :
a 1
a 1
a 2
b 2
c 3
d 4
NOTE: Multimap holds multiple entries of the same key .
Don't forget to add :
#include<map>
This is the header file that defines map and multimap containers. Forgetting to include this header, will result in errors.
Method 2 : Using pair
Initializing key and value separately to pair, and inserting the pair object to the multimap. Here, we are using a single pair object.
In Method 3 we use a new pair object everytime we insert an entry into the multimap.
Note: You can also initialise the pair directly as given in Method 3
pair<char, int> x;
std::multimap<char, int> m; //empty multimap container
x.first='a';x.second=1;
m.insert(x); //inserting (a,1)
x.first='a';x.second=1;
m.insert(x); //inserting (a,1)
x.first='b';x.second=2;
m.insert(x); //inserting (b,2)
x.first='c';x.second=3;
m.insert(x); //inserting (c,3)
x.first='a';x.second=2;
m.insert(x); //inserting (a,2)
x.first='d';x.second=4;
m.insert(x); //inserting (d,4)
Method 3 : Using pair
STL pair is a container that holds two values. The datatypes of these values may be the same or may be different. Example : <int, int>
or <char, int>
or <int, char>
or <string, int>
, etc.
Note: You must have noticed that this is similar to Method 1.
Method 1 uses make_pair and here we use pair. Yes, these methods look very similar. But the difference is that you need to strictly specify the types of both the elements in pair, whereas make_pair will create a pair of the type of the elements that are passed to it, without having to explicitly specify the type.
Notice in this code, we are specifying <char, int>
every time we insert an entry into the multimap.
std::multimap<char, int> m; //empty multimap container
m.insert(pair<char, int>('a',1)); //inserting (a,1)
m.insert(pair<char, int>('a',1)); //inserting (a,1)
m.insert(pair<char, int>('b',2)); //inserting (b,2)
m.insert(pair<char, int>('c',3)); //inserting (c,3)
m.insert(pair<char, int>('a',2)); //inserting (a,2)
m.insert(pair<char, int>('d',4)); //inserting (d,4)
Method 4 :Initializing with initializer list
An initializer list is used to initialize the data members of a class.
Here we do not use the insert() function and we can directly finish the initialization in a single line !
std::multimap<char, int> m={
{'a',1}, {'a',1}, {'b',2}, {'c',3}, {'a',2}, {'d',4}
};
Method 5 : Constructing a multimap n from another multimap m
Here we have a multimap m and we assign the values of m to a new multimap n by specifying the start and end iterator (To copy the desired elements from a given start iterator to a given end iterator)
Assigning elements from map m to map n :
Using range constructor :
std::multimap<char, int> n(m.begin(),m.end());
Method 6 : Using copy constructor
Constructing a multimap n from another multimap m by passing the map object . Similar to the previous method, but here we do not specify the start and end position from where we want to copy elements from multimap m. We copy every entry present in m to n.
std::multimap<char, int> n(m);
Method 7 : Using emplace_hint()
Inserts the given key and value pair into the multimap container with a given hint.
The hint does not affect the position of insertion, but only affects the speed of insertion, since it points to the position from where search for the ordering is to be started.
Syntax :
multimap_name.emplace_hint(position, key, element)
Here the three paraments are :
- key : The key to be inserted into the multimap container
- element : The element, that is, the value to be inserted into the multimap container
- position : position from where the search operation for the ordering is to be started, which makes insertion faster.
Code :
std::multimap<char, int> mp; //empty multimap container
mp.emplace_hint(mp.begin(), 'a', 1); //inserting (a,1)
mp.emplace_hint(mp.begin(), 'a', 1); //inserting (a,1)
mp.emplace_hint(mp.begin(), 'b', 2); //inserting (b,2)
mp.emplace_hint(mp.begin(), 'c', 3); //inserting (c,3)
mp.emplace_hint(mp.begin(), 'a', 2); //inserting (a,2)
mp.emplace_hint(mp.begin(), 'd', 4); //inserting (d,4)
Notice the in all the above examples of initializing a multimap with key-value pairs, the key 'a' was inserted multiple times into the multimap container. Also, there were no restrictions on the value of 'a'. The value of 'a' may be a duplicate or not.
Printing the contents of the multimap :
Method 1 :
Printing the contents of multimap m using auto:
for(auto& el : m)
cout<<el.first<<" "<<el.second<<endl;
Method 2 :
Iterating over the multimap using iterator and displaying the contents of the multimap :
multimap<char, int>::iterator it;
for(it=m.begin();it!=m.end();it++)
cout<<it->first<<" "<<it->second<<"\n";
Method 3 :
Iterating over multimap using a range based for loop and displaying the contents of the container :
for(pair<char, int> elem: m)
cout<<elem.first<<" "<<elem.second<<endl;
Question
Difference between STL map and a multimap ?
With this article at OpenGenus, you must have the complete idea of Different ways of Initializing multimap in C++. Enjoy.