STL: unordered_map usage notes
Reference website:
1. General
unordered_ The template of map is defined as follows:
template < class Key, // unordered_map::key_type class T, // unordered_map::mapped_type class Hash = hash<Key>, // unordered_map::hasher class Pred = equal_to<Key>, // unordered_map::key_equal class Alloc = allocator< pair<const Key,T> > // unordered_map::allocator_type > class unordered_map;
unordered_map is an association container that stores elements based on key value and mapping, namely key value. Allows you to quickly find elements based on keys. In unordered_ In the map, the key value uniquely identifies the element, and the mapped value is an object of the content associated with the object.
For order and disorder:
- unordered_ The disorder of map is reflected in that the internal storage structure is hash table, so that the elements can be accessed quickly through key values.
- The corresponding ordered associated container is map. The order of map is reflected in the internal storage structure of red black tree. During storage, the elements are automatically arranged in the order from small to large.
The internal storage structure also determines unordered_map and map differ in some features:
- Search efficiency
- unordered_map search efficiency is higher, which can reach O(1), but the range iteration efficiency of element subset is low.
- For map, according to the traversal order of middle order traversal, it is convenient to iterate to get the elements from small to large
Unordered mapping implements the direct access operator (operator []), which allows direct access to mapped values using their key values as parameters. Iterators in containers are at least forward iterators forward iterators.
2. Properties
2.1 relevance
The elements in the associated container are referenced by their keys, not by their absolute position in the container.
2.2 disorder
Unordered containers use hash tables to organize their elements, which allow quick access to elements through their keys.
2.3 Map mapping
Each element associates a key with a mapping value: a key means identifying the element whose main content is the mapping value.
2.4 uniqueness of key
No two elements in the container have the same key
2.5 Allocator-aware
The container uses an allocator object to dynamically handle its storage requirements.
3. Template parameters
template < class Key, // unordered_map::key_type class T, // unordered_map::mapped_type class Hash = hash<Key>, // unordered_map::hasher class Pred = equal_to<Key>, // unordered_map::key_equal class Alloc = allocator< pair<const Key,T> > // unordered_map::allocator_type > class unordered_map;
-
key
Type of key value. unordered_ Each element in the map is uniquely identified by its key value.
-
T
Type of mapping value. unordered_ Each element in the map is used to store some data as its mapping value.
-
Hash
A unary function object type that accepts an object of type key as a parameter and returns size based on the object_ Unique value of type T. This can be a class that implements a function call operator or a pointer to a function (see constructor). The default is hash < key >.
-
Pred
Accepts two key type parameters and returns a binary predicate of type bool. Expression PRED (a, b). PRED is an object of this type. A and B are key values and return true. If yes, it should be considered equivalent to B. This can be a class that implements a function call operator or a pointer to a function (see constructor as an example). This defaults to equal_ To < key >, which returns the same result as applying the equality operator (a==b).
-
Allloc
The type of allocator object used to define the storage allocation model. By default, the allocator class template is used, which defines the simplest memory allocation model and is independent of values.
4. Member function
4.1 constructor and initialization
(1) The default constructor of the template class, creating an empty unordered_map
unordered_map<int, string> umap;
(2) Initialize with initialization list
unordered_map<int, string> umap = unordered_map<int, string>({{1,"a"},{2,"b"}}); // Explicitly call C + + constructor unordered_map<int, string> umap2({{3,"c"},{4,"d"}}); // Implicit call constructor, more concise unordered_map<string, string> umap{ {"TaoBao","https://www.taobao.com/"}, {"JD.COM","https://www.jd.com/"}, {"Tmall mall","https://jx.tmall.com/"} };
(3) Copy constructor initialization
// copy constructor unordered_map<int, string> umap4(umap3);
(4) Iterator initialization
// range unordered_map<int, string> umap5(umap1.begin(), umap1.end());
(5) Copy initialization
typedef std::unordered_map<std::string,std::string> stringmap; first = {{"AAPL","Apple"},{"MSFT","Microsoft"}}; // init list second = {{"GOOG","Google"},{"ORCL","Oracle"}}; // init list third = merge(first,second); // move first = third; // copy
4.2 capacity
(1) Is it empty
cout << "first " << (first.empty() ? "is empty" : "is not empty") << endl; cout << "first " << (second.empty() ? "is empty" : "is not empty") << endl;
(2) Current capacity
cout << "thrid.size is" << third.size() << endl;
4.3 iteration
/** Iteration **/ for (auto it = first.begin(); it != first.end(); it++){ cout << " " << it->first << ":" << it->second; } cout<<endl;
4.4 access to elements
(1)operator[]
first["GOOG"] = "Google"; // new element inserted first["AAPL"] = "Apple"; // new element inserted first["MSFT"] = "Microsoft"; // new element inserted first["BOB"] = "Bob"; string brand1 = first["GOOG"]; // read first["BOB"] = ""; // writen for (auto it = first.begin(); it != first.end(); it++){ cout << " " << it->first << ":" << it->second; } cout<<endl;
(2)at
unrdered_map<string,int> mymap = { {"Mars", 3000}, {"Saturn", 60000}, {"Jupiter", 70000}}; mymap.at("Mars") = 3396; mymap.at("Saturn") += 127; mymap.at("Jupiter") = mymap.at("Saturn") + 9638; for (auto& x: mymap) { std::cout << x.first << ": " << x.second << std::endl; }
4.5 element search
(1)find
The prototype of the find function is as follows:
iterator find ( const key_type& k ); const_iterator find ( const key_type& k ) const;
The find function can be used to get the iterator of the element:
std::unordered_map<std::string,double> mymap1 = { {"mom",5.4}, {"dad",6.1}, {"bro",5.9} }; string person = "dad"; unordered_map<std::string,double>::const_iterator got = mymap1.find(person); if(got == mymap1.end()){ cout << "not found" << endl; }else{ cout << got->first << " is " << got->second << endl; }
Notice how iterators are declared:
unordered_map<string,double>::const_iterator
(2)count
The member function count determines whether there is a key value k in the set. The prototype of the function is as follows:
size_type count ( const key_type& k ) const;
Where size_type is an integer variable. If there is key k in the unordered map, the return value is 1; otherwise, the return value is 0.
4.6 modification
(1) Element insertion
-
operator[]
Using the operator map_name [key_name] = value, which overwrites the value value of the corresponding key. If the key value is a non-existent key, then the insertion of a new element is realized.
-
emplace()
In unordered_ Insert a new element into the map (if its key is unique). This new element is constructed using args as an argument to the element constructor.
Only if no element in the container has a key equivalent to the element to be placed (the key in the unordered_map is unique) , Will be inserted.
If inserted, this will actually increase the container size by one.
There is a similar member function insert, which copies or moves existing objects into the container.
// unordered_map::emplace #include <iostream> #include <string> #include <unordered_map> int main () { std::unordered_map<std::string,std::string> mymap; mymap.emplace ("NCC-1701", "J.T. Kirk"); mymap.emplace ("NCC-1701-D", "J.L. Picard"); mymap.emplace ("NCC-74656", "K. Janeway"); std::cout << "mymap contains:" << std::endl; for (auto& x: mymap) std::cout << x.first << ": " << x.second << std::endl; std::cout << std::endl; return 0; }
-
insert()
The insertion of insert is similar to the insertion of replace. Only when the key is unique can it be inserted, and the size increases.
The insertion form of insert is more flexible than that of empty:
(1) pair<iterator,bool> insert ( const value_type& val ); (2) template <class P> pair<iterator,bool> insert ( P&& val ); (3) iterator insert ( const_iterator hint, const value_type& val ); (4) template <class P> iterator insert ( const_iterator hint, P&& val ); (5) template <class InputIterator> void insert ( InputIterator first, InputIterator last ); (6) void insert ( initializer_list<value_type> il );
/** Element insertion**/ // insert unordered_map<string,double> myrecipe, mypantry = {{"milk",2.0},{"flour",1.5}};; pair<string,double> myshopping ("baking powder",0.3); myrecipe.insert(myshopping); // copy insertion myrecipe.insert(mypantry.begin(), mypantry.end()); // range inseration myrecipe.insert({{"sugar",0.8},{"salt",0.1},{"sugar",0.9}}); // initializer list inseration cout << "myrecipe contains: " << endl; for(auto& x:myrecipe){ cout << x.first << ":" << x.second << " "; }
(2) Element deletion
The erase() method is used to delete elements. There are many forms of deletion:
by position (1) | iterator erase ( const_iterator position ); |
---|---|
by key (2) | size_type erase ( const key_type& k ); |
range (3) | iterator erase ( const_iterator first, const_iterator last ); |
//erase std::unordered_map<std::string,std::string> mymap3; // populating container: mymap3["U.S."] = "Washington"; mymap3["U.K."] = "London"; mymap3["France"] = "Paris"; mymap3["Russia"] = "Moscow"; mymap3["China"] = "Beijing"; mymap3["Germany"] = "Berlin"; mymap3["Japan"] = "Tokyo"; cout << endl; cout << "------------------------------------------" << endl; // Depending on the location, delete the first: mymap3.erase(mymap3.begin()); // According to key mymap3.erase("France"); // range mymap3.erase(mymap3.find("Germany"), mymap3.end()); for (auto& x : mymap3) { cout << x.first << ": " << x.second << " "; }