Learning notes 3 of STL Standard Template Library (STL hash container)

Posted by nelsons on Fri, 08 Oct 2021 09:04:42 +0200

  • The underlying implementation of associative container (sorting) adopts tree storage structure, more specifically red black tree structure;
  • The underlying implementation of unordered container (hash) adopts the storage structure of hash table.

  • Different methods are adopted based on the underlying implementation data structure Therefore, compared with associative containers, unordered containers have the following two characteristics:
  • The key value pairs stored in the unordered container are unordered, and the storage location of each key value pair depends on the key in the key value pair,
  • Compared with associative containers, unordered containers are good at finding the corresponding value through the specified key (the average time complexity is O(1)); However, for traversing the elements stored in the container using iterators, the execution efficiency of unordered containers is not as efficient as associative containers.
unordered_map Store key value pairs < key, value > type elements, where the key values of each key value pair are not allowed to be repeated, and the key value pairs stored in the container are out of order.
unordered_multimapAnd unordered_ The only difference between maps is that the container allows multiple key value pairs with the same key to be stored.
unordered_setInstead of storing data in the form of key value pairs, the data element itself is directly stored (of course, it can also be understood that all the key value pairs stored in the container are key value pairs equal to the value. Just because they are equal, only value can be stored). In addition, the elements stored in the container cannot be repeated, and the elements stored in the container are also out of order.
unordered_multisetAnd unordered_set the only difference is that the container allows elements with the same value to be stored.

  unordered_map class

#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;
int main()
{
    //Create and initialize an unordered_map container, which stores key value pairs of < string, string > type
    std::unordered_map<std::string, std::string> my_uMap{
        {"C Language course","http://c.biancheng.net/c/"},
        {"Python course","http://c.biancheng.net/python/"},
        {"Java course","http://c.biancheng.net/java/"} };
    //Finding the value corresponding to the specified key is more efficient than associative containers
    string str = my_uMap.at("C Language course");
    cout << "str = " << str << endl;
    //Using iterators to traverse hash containers is not as efficient as associative containers
    for (auto iter = my_uMap.begin(); iter != my_uMap.end(); ++iter)
    {
        //pair type key value pairs are divided into two parts
        cout << iter->first << " " << iter->second << endl;
    }
    return 0;
}

str = http://c.biancheng.net/c/
C language tutorial http://c.biancheng.net/c/
Python tutorial http://c.biancheng.net/python/
Java Tutorial http://c.biancheng.net/java/

Member methodfunction
begin()Returns a forward iterator pointing to the first key value pair in the container.
end() Returns a forward iterator pointing to the position after the last key value pair in the container.
cbegin()The function is the same as that of begin(), but the const attribute is added, that is, the iterator returned by this method cannot be used to modify the key value pairs stored in the container.
cend()The function is the same as that of end(), but the const attribute is added on the basis of it, that is, the iterator returned by this method cannot be used to modify the key value pairs stored in the container.
empty()If the container is empty, return true; Otherwise, false.
size()Returns the number of key value pairs stored in the current container.
max_size()Returns the maximum number of key value pairs that the container can hold. The return values are different for different operating systems.
operator[key]The [] operator is overloaded in the template class. Its function is to access the elements in the array. As long as the key key of a key value pair is given, the corresponding value of the key can be obtained. Note that if there is no key value pair with key as the key in the current container, it will use the key to insert a new key value pair into the current container.
at(key)Returns the value corresponding to the key stored in the container. If the key does not exist, an out will be thrown_ of_ Range exception.  
find(key)Find the key value pair with key as the key, and if found, return a forward iterator pointing to the key value pair; Conversely, it returns an iterator pointing to the position after the last key value pair in the container (if the iterator returned by the end() method).
count(key)Find the number of key value pairs with key in the container.
equal_range(key)Returns a pair object containing 2 iterators, which indicates the range of key value pairs with key in the current container.
emplace()Adding a new key value pair to the container is more efficient than the insert() method.
emplace_hint()Adding a new key value pair to the container is more efficient than the insert() method.
insert() Add a new key value pair to the container.
erase()Deletes the specified key value pair.
clear() Empty the container, that is, delete all key value pairs stored in the container.
swap()Exchange 2 unordered_ The map container stores key value pairs on the premise that the types of the two containers must be completely equal.
bucket_count()Returns the number of buckets (a linear linked list represents a bucket) used when storing key value pairs at the bottom of the current container.
max_bucket_count()Return to the current system, unordered_ The maximum number of buckets that can be used at the bottom of the map container.
bucket_size(n)Returns the number of key value pairs stored in the nth bucket.
bucket(key)Returns the bucket number of the key value pair with key as the key.
load_factor()Return unordered_ The current load factor in the map container. Load factor refers to the ratio of the number of key value pairs stored in the current container (size ()) to the number of buckets used (bucket_count()), that is, load_factor() = size() / bucket_count().
max_load_factor()Returns or sets the current unordered_ Load factor of the map container.
rehash(n)Set the number of buckets used at the bottom of the current container to n.
reserve()Set the number of buckets (that is, the return value of the bucket_count() method) to the number required to hold at least count elements (not exceeding the maximum load factor), and rearrange the container.
hash_function()Returns the hash function object used by the current container.
#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;
int main()
{
    //Create an empty umap container
    unordered_map<string, string> umap;
    //Add a new key value pair to the umap container
    umap.emplace("Python course", "http://c.biancheng.net/python/");
    umap.emplace("Java course", "http://c.biancheng.net/java/");
    umap.emplace("Linux course", "http://c.biancheng.net/linux/");
    //The output umap stores the number of key value pairs
    cout << "umap size = " << umap.size() << endl;
    //Use the iterator to output all key value pairs stored in the umap container
    for (auto iter = umap.begin(); iter != umap.end(); ++iter) {
        cout << iter->first << " " << iter->second << endl;
    }
    return 0;
}

 umap size = 3
Python tutorial http://c.biancheng.net/python/
Linux tutorial http://c.biancheng.net/linux/
Java Tutorial http://c.biancheng.net/java/

Iterator iterator

Member methodfunction
begin()Returns a forward iterator pointing to the first key value pair in the container.
end() Returns a forward iterator pointing to the position after the last key value pair in the container.
cbegin()The function is the same as that of begin(), but the const attribute is added, that is, the iterator returned by this method cannot be used to modify the key value pairs stored in the container.
cend()The function is the same as that of end(), but the const attribute is added on the basis of it, that is, the iterator returned by this method cannot be used to modify the key value pairs stored in the container.
find(key)Find the key value pair with key as the key, and if found, return a forward iterator pointing to the key value pair; Conversely, it returns an iterator pointing to the position after the last key value pair in the container (if the iterator returned by the end() method).
equal_range(key)Returns a pair object containing 2 iterators, which indicates the range of key value pairs with key in the current container.
#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;
int main()
{
    //Create umap container
    unordered_map<string, string> umap{
        {"Python course","http://c.biancheng.net/python/"},
        {"Java course","http://c.biancheng.net/java/"},
        {"Linux course","http://c.biancheng.net/linux/"} };
    cout << "umap Stored key value pairs include:" << endl;
    //Traverse all key value pairs in the output umap container
    for (auto iter = umap.begin(); iter != umap.end(); ++iter) {
        cout << "<" << iter->first << ", " << iter->second << ">" << endl;
    }
    //Gets the forward iterator pointing to the specified key value pair
    unordered_map<string, string>::iterator iter = umap.find("Java course");
    cout <<"umap.find(\"Java course\") = " << "<" << iter->first << ", " << iter->second << ">" << endl;
    return 0;
}

  The key value pairs stored in umap include:
< Python tutorial, http://c.biancheng.net/python/ >
< Linux tutorial, http://c.biancheng.net/linux/ >
< java tutorial, http://c.biancheng.net/java/ >
umap.find("Java tutorial") = < java tutorial, http://c.biancheng.net/java/ >

Get element []. at()

#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;
int main()
{
    //Create umap container
    unordered_map<string, string> umap{
        {"Python course","http://c.biancheng.net/python/"},
        {"Java course","http://c.biancheng.net/java/"},
        {"Linux course","http://c.biancheng.net/linux/"} };
    //Get the value corresponding to the Java tutorial
    string str = umap["Java course"];
    cout << str << endl;
    return 0;
}

unordered_ In the map container class template, the [] operator is overloaded, so that we can obtain the value corresponding to the key through the key of the target key value pair like "using subscripts to access elements in an ordinary array".

It should be noted that if the key value pair with the element specified in the [] operator as the key is not stored in the current container, the function of the [] operator will change to: add the key value pair with the target element as the key to the current container. for instance:

As you can see, when using the [] operator to unordered_ When adding key value pairs to the map container, there are two situations:

  1. When the [] operator is on the right side of the assignment number (=), the key of the newly added key value pair is the element in the [] operator, and its value is the default value of the value type required by the key value pair (the default value of string type is an empty string);
  2. When the [] operator is to the left of the assignment number (=), the key of the newly added key value pair is the element within the [] operator, and its value is the element to the right of the assignment number.

unordered_ The map class template also provides an at() member method. Like the [] operator, the at() member method also needs to find the value corresponding to the key from the container according to the specified key; The difference is that if the search fails in the current container, the method will not add a new key value pair to the container, but directly throw out_of_range exception.

Different from the previous method, the find() method obtains a forward iterator, and the direction of the iterator can be divided into the following two cases:

  1. When the find() method successfully finds a key value pair with the specified element as the key, its returned iterator points to the key value pair;
  2. When the find() method fails, the iterator returned by the find() method, like the iterator returned by the end() method, points to the position after the last key value pair in the container.
#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;
int main()
{
    //Create umap container
    unordered_map<string, string> umap{
        {"Python course","http://c.biancheng.net/python/"},
        {"Java course","http://c.biancheng.net/java/"},
        {"Linux course","http://c.biancheng.net/linux/"} };
    //Search succeeded
    unordered_map<string, string>::iterator iter = umap.find("Python course");
    cout << iter->first << " " << iter->second << endl;
    //Search failed
    unordered_map<string, string>::iterator iter2 = umap.find("GO course");
    if (iter2 == umap.end()) {
        cout << "There are no in the current container\"GO course\"Key value pair for key";
    }
    return 0;
}

insert method

#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;
int main()
{
    //Create an empty umap container
    unordered_map<string, string> umap;
    //Build key value pairs to add
    std::pair<string, string>mypair("STL course", "http://c.biancheng.net/stl/");
    //Create a pair type variable that receives the value returned by the insert() method
    std::pair<unordered_map<string, string>::iterator, bool> ret;
    //The first syntax format for calling the insert() method
    ret = umap.insert(mypair);
    cout << "bool = " << ret.second << endl;
    cout << "iter -> " << ret.first->first <<" " << ret.first->second << endl;
   
    //The second syntax format for calling the insert() method
    ret = umap.insert(std::make_pair("Python course","http://c.biancheng.net/python/"));
    cout << "bool = " << ret.second << endl;
    cout << "iter -> " << ret.first->first << " " << ret.first->second << endl;
    return 0;
}

  Delete element erase

iterator erase ( const_iterator position );

size_type erase ( const key_type& k );

iterator erase ( const_iterator first, const_iterator last );

#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;
int main()
{
    //Create umap container
    unordered_map<string, string> umap{
        {"STL course", "http://c.biancheng.net/stl/"},
        {"Python course", "http://c.biancheng.net/python/"},
        {"Java course", "http://c.biancheng.net/java/"} };
    //First points to the first key value pair
    unordered_map<string, string>::iterator first = umap.begin();
    //Last points to the last key value pair
    unordered_map<string, string>::iterator last = umap.end();
    //Delete key value pairs within the [fist, last] range
    auto ret = umap.erase(first, last);
    //Output key value pairs stored in the umap container
    for (auto iter = umap.begin(); iter != umap.end(); ++iter) {
        cout << iter->first << " " << iter->second << endl;
    }
    return 0;
}

unordered_set

Unordered_set container can be literally translated as "unordered set container", that is, unordered_set container is very similar to set container. The only difference is that set container will sort the stored data by itself, while unordered_set container will not.

In general, the unordered_set container has the following features:

  1. The data is no longer stored in the form of key value pairs, but the value of the data is directly stored;
  2. The values of each element stored in the container are not equal to each other and cannot be modified.
  3. Internally stored data is not sorted
#include <iostream>
#include <string>
#include <unordered_set>
using namespace std;
int main()
{
    //Create an empty unordered_set container
    std::unordered_set<std::string> uset;
    //Add data to the uset container
    uset.emplace("http://c.biancheng.net/java/");
    uset.emplace("http://c.biancheng.net/c/");
    uset.emplace("http://c.biancheng.net/python/");
    //View the number of storage elements in the current uset container
    cout << "uset size = " << uset.size() << endl;
    //Traverse all elements stored in the output uset container
    for (auto iter = uset.begin(); iter != uset.end(); ++iter) {
        cout << *iter << endl;
    }
    return 0;
}

 

Topics: C++