Maps are associate containers. They associate a key and a value as pair and store them. There are four kinds of maps in C++
map
multimap
unordered_map
unordered_multimap
map
Internally, keys are sorted following a strict weak ordering criteria - default is less<Key>
Implemented using binary search trees, so access takes O(log n)
1 2 3 4 5 template < class Key , // map : :key_type class T , // map : :mapped_type class Compare = less<Key>, class Alloc = allocator<pair <const Key,T> > > class map ;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 #include <map> map <int ,string > m;m[1 ] = "apple" ; m[2 ] = "strawberry" ; m[3 ] = "blueberry" ; cout << "1 => " << m[1 ] << "\n" ;cout << "is not present = " << (m[4 ] == "" ) << "\n" ;cout << "2 => " << m.at(2 ) << "\n" ;cout << "size = " << m.size() << "\n" ;if (m.find(2 ) != m.end()) cout << "key-2 is present" << "\n" ; if (m.find(6 ) == m.end()) cout << "key-6 is not present" << "\n" ; m.insert(pair <int ,string > (1 , "apple" )); m.insert(pair <int ,string > (4 , "orange" )); auto ret = m.insert(pair <int ,string > (5 , "pineapple" ));auto already_there = m.insert(pair <int ,string > (5 , "pineapple" ));if (ret.second) cout << "element was inserted newly" << "\n" ; if (!already_there.second) cout << "element was already there" << "\n" ; cout << "access inserted item via iterator" << "\n" ;cout << "key = " << ret.first->first << "\n" ;cout << "value = " << ret.first->second << "\n" ;m.erase(m.find(1 )); for (auto ele: m) { cout << "first = " << ele.first << "\n" ; cout << "second = " << ele.second << "\n" ; }
multimap Like map, but key could occur more than once.
1 2 3 4 5 template < class Key , // multimap : :key_type class T , // multimap : :mapped_type class Compare = less<Key>, class Alloc = allocator<pair <const Key,T> > > class multimap ;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #include <map> multimap <int ,string > m;m.insert(pair <int ,string > (1 , "apple" )); m.insert(pair <int ,string > (1 , "pineapple" )); m.insert(pair <int ,string > (4 , "orange" )); m.insert(pair <int ,string > (2 , "watermelon" )); cout << m.find(1 )->second << "\n" ;if (m.find(6 ) == m.end()) cout << "key value of 6 not found" << "\n" ; auto iter = m.equal_range(1 );for (auto it = iter.first; it != iter.second; ++it) cout << it->second << "\n" ; m.erase(1 ); for (auto ele: m) { cout << "key = " << ele.first << "\n" ; cout << "value = " << ele.second << "\n" ; }
unordered_map
Internally, keys are not sorted and a hash value of key is used to organise the kv pair in buckets.
Faster access time due to hash function -> constant average time
1 2 3 4 5 6 template < class Key , // unordered_map : :key_type class T , // unordered_map : :mapped_type class Hash = hash<Key>, class Pred = equal_to<Key>, class Alloc = allocator< pair <const Key,T> > > class unordered_map ;
1 2 3 4 5 6 7 8 9 #include <unordered_map> unordered_map <int ,string > m;m[1 ] = "apple" ; cout << m[1 ] <<"\n" ;
unordered_multimap
Like unordered_map
, but the key could occur more than once.
Faster compared to multimap
, as it uses hash function to internally store kv pairs in buckets based on the key.
1 2 3 4 5 6 template < class Key , // unordered_multimap : :key_type class T , // unordered_multimap : :mapped_type class Hash = hash<Key>, class Pred = equal_to<Key>, class Alloc = allocator< pair <const Key,T> > > class unordered_multimap ;
1 2 3 4 5 6 7 8 9 #include <unordered_map> unordered_multimap <int ,string > m;m.insert(pair <int ,string > (1 , "apple" )); m.insert(pair <int ,string > (1 , "pineapple" )); cout << m.find(1 )->second << "\n" ;
References