菜鸟笔记
提升您的技术认知

C++ unordered_map的使用

std::unordered_map(C++11)

template < class Key,                                    // unordered_map::key_type
           class T,                                      // unordered_map::mapped_type
           class Hash = hash,                       // unordered_map::hasher
           class Pred = equal_to,                   // unordered_map::key_equal
           class Alloc = allocator< pair<const Key,T> >  // unordered_map::allocator_type
           > class unordered_map;

无序的映射
无序映射是存储键值和映射值组合形成的元素的关联容器,它允许根据键快速检索单个元素。
在unordered_map中,键值通常用于惟一地标识元素,而映射的值是一个对象,其内容与此键相关联。键和映射值的类型可能不同
在内部,unordered_map中的元素没有对键值或映射值以任何特定的顺序排序,但组织成buckets的形式都取决于他们的散列值,以便通过它的键值快速访问单个元素(平均一个恒定的平均时间复杂度)。

unordered_map容器比map容器能更快地通过它们的键访问单个元素,尽管它们通常对于元素子集的范围迭代效率较低
无序映射实现了直接访问操作符(operator[]),该操作符允许使用其键值作为参数直接访问映射值。
容器中的迭代器至少是前向迭代器forward iterators。

 

Container properties容器属性

Associative关联性
关联容器中的元素由它们的键引用,而不是由它们在容器中的绝对位置引用。
Unordered无序性

无序容器使用散列表来组织它们的元素,散列表允许通过它们的键快速访问元素。

Map映射

每个元素都将一个键关联到一个映射值:键表示标识其主要内容为映射值的元素。

Unique keys
容器中的任何两个元素都不能具有相同的键。
Allocator-aware

容器使用一个分配器对象来动态地处理它的存储需求。

 

Template parameters模版参数

key:

键值的类型。unordered_map中的每个元素都由其键值唯一标识。
别名为成员类型unordered_map::key_type。

T:

映射值的类型。unordered_map中的每个元素都用于将一些数据存储为其映射值。
别名为成员类型unordered_map::mapped_type。注意,这与unordered_map::value_type(参见下面)不同。

Hash:
一个一元函数对象类型,它接受一个key类型的对象作为参数,并基于它返回一个类型size_t的唯一值。它可以是实现函数调用操作符的类,也可以是指向函数的指针(参见构造函数的示例)。默认值是hash,它返回一个散列值,碰撞概率接近1.0/std::numeric_limits::max()。

unordered_map对象使用此函数返回的散列值在内部组织其元素,从而加快了定位单个元素的过程。

别名为成员类型unordered_map::hasher。
Pred:(
判断两个键值是否相同
一个二进制谓词,它接受两个键key类型的参数并返回一个bool。表达式pred (a, b), pred是这种类型的一个对象,a和b是键值,如果a应考虑相当于b则返回true。这可以是一个实现一个函数调用操作符或指向函数的指针(见构造函数为例)的类。这默认为equal_to,它返回的结果与应用equal-to操作符相同(a==b)。

unordered_map对象使用这个表达式来确定两个元素键是否相等。使用此谓词,unordered_map容器中的任何两个元素都不能具有产生true的键。

别名为成员类型unordered_map::key_equal。
Alloc:
用于定义存储分配模型的分配器对象的类型。默认情况下,使用的是分配器类模板,它定义了最简单的内存分配模型,并且是与值无关的。

别名为成员类型unordered_map::allocator_type。
在unordered_map成员函数的引用中,模板参数使用相同的名称(Key、T、Hash、Pred和Alloc)。

unordered_map容器元素的迭代器同时访问键和映射值。为此,该类定义了一个名为value_type的类,它是一个pair类,它的第一个值对应于键类型的const版本(模板参数键),第二个值对应于映射的值(模板参数T):
typedef pair<const Key, T> value_type;

unordered_map容器的迭代器指向此value_type的元素。因此,对于一个指向map元素的迭代器来说,它的键和映射值可以分别通过以下方式访问:

unordered_map::iterator it;
(*it).first;             // the key value (of type Key)
(*it).second;            // the mapped value (of type T)
(*it);                   // the "element value" (of type pair) 

当然,任何其他直接访问操作符,如->或[]都可以使用,例如:

it->first;               // same as (*it).first   (the key value)
it->second;              // same as (*it).second  (the mapped value) 

 

Member types成员类型

以下别名是unordered_map的成员类型。它们被成员函数广泛用作参数和返回类型:

成员类型 定义 notes
key_type 第一个模版参数(Key)  
mapped_type 第二个模版参数(T)  
value_type pair  
hasher 第三个模版参数(Hash) 默认为:hash
key_equal 第四个模版参数(Pred) 默认为:equal_to
allocator_type 第五个模版参数(Alloc) 默认为:allocator
reference Alloc::reference  
const_reference Alloc::const_reference  
pointer Alloc::pointer 默认为allocator: value_type*
const_pointer Alloc::const_pointer 默认为allocator: const value_type*
iterator value_type的前向迭代器  
const_iterator const value_type的前向迭代器  
local_iterator value_type的前向迭代器  
const_local_iterator const value_type的前向迭代器  
size_type 一个无符号的整数类型 等同于size_t
difference_type 一个有符号的整数类型 等同于ptrdiff_t

Member functions成员函数

1)构造函数

empty (1)    
explicit unordered_map ( size_type n = /* see below */,
                         const hasher& hf = hasher(),
                         const key_equal& eql = key_equal(),
                         const allocator_type& alloc = allocator_type() );
explicit unordered_map ( const allocator_type& alloc );

range (
2) template <class InputIterator> unordered_map ( InputIterator first, InputIterator last, size_type n = /* see below */, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& alloc = allocator_type() );
copy (
3) unordered_map ( const unordered_map& ump ); unordered_map ( const unordered_map& ump, const allocator_type& alloc );
move (
4) unordered_map ( unordered_map&& ump ); unordered_map ( unordered_map&& ump, const allocator_type& alloc );
initializer list (
5) unordered_map ( initializer_list il, size_type n = /* see below */, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& alloc = allocator_type() );

构建unordered_map
构造一个unordered_map容器对象,根据使用的构造函数版本初始化其内容:

(1)空容器构造函数(默认构造函数)
构造一个空的unordered_map对象,该对象不包含元素,大小为0。
它可以使用特定的hasher、key_equal和分配器对象以及最少数量的散列桶来构造容器。
(2)range构造函数
构造一个unordered_map对象,该对象包含[first,last)范围内每个元素的副本。
(3)复制构造函数(以及复制分配器)
对象初始化为具有与unordered_map对象ump相同的内容和属性。
(4)移动构造函数(以及使用分配器移动)
对象获取rvalue右值ump的内容。
(5)初始化器列表
用列表的内容初始化容器。

 

参数:

n:

初始桶的最小数量。
这不是容器中的元素数量,而是构造内部哈希表所需的最小槽数。
如果没有指定这个参数,构造函数将自动确定(以一种依赖于特定库实现的方式)。
成员类型size_type是无符号整数类型。

hf:

hasher函数对象。hasher是一个基于作为参数传递给它的容器对象键值key而返回整数值的函数,即该整数值 = hasher(key)。
成员类型hasher在unordered_map中定义为其第三个模板参数(Hash)的别名。

eql:

如果作为参数传递的两个容器对象键key被认为是相等的,则返回true。
成员类型key_equal在unordered_map中定义为其第四个模板参数(Pred)的别名。

alloc:

要使用的分配器对象,而不是构造新对象。
对于使用默认分配器类模板版本的类实例化,此参数不相关。
成员类型allocator_type在unordered_map中定义为其第五个模板参数(Alloc)的别名。

first, last:
将迭代器输入到范围的初始和最终位置。使用的范围是[first,last),它包括first和last之间的所有元素,包括first指向的元素,但不包括last指向的元素。

函数模板类型可以是任何类型的输入迭代器。
ump:
另一个相同类型的unordered_map对象(具有相同的类模板参数),其内容可以复制或移动。
il:
一个initializer_list对象。

这些对象是由初始化器列表声明器自动构造的。

成员类型value_type是容器中元素的类型,在unordered_map中定义为pair,其中成员类型key_type是第一个模板参数(key类型)的别名,而mapped_type是第二个模板参数(映射mapped类型,T)的别名。
举例:
#include 
#include <string>
#include 
using namespace std;

using stringmap = unordered_map<string, string>;

stringmap merge(stringmap a, stringmap b){
    stringmap temp{a};
    temp.insert(b.begin(), b.end());
    return temp;
}

int main(){
    stringmap first;
    stringmap second {{"apple", "red"},{"lemon","yellow"}};
    stringmap third {{"orange","orange"}, {"strawberry", "red"}};
    stringmap fourth (second);
    stringmap fifth (merge(third, fourth));
    stringmap sixth (fifth.begin(), fifth.end());

    cout << "sixth contains : ";
    for(auto& x:sixth) cout << "  " << x.first << ":" << x.second;
    cout << endl;
    return 0;
}

返回:

sixth contains :   orange:orange  strawberry:red  lemon:yellow  apple:red

 

2)析构函数

~unordered_map();

销毁无序的映射
销毁容器对象。这将调用所包含元素的每个析构函数,并释放由unordered_map容器分配的所有存储容量。

 

3)赋值操作

copy (1)    
unordered_map& operator= ( const unordered_map& ump );

move (
2) unordered_map& operator= ( unordered_map&& ump );
initializer list (
3) unordered_map& operator= ( intitializer_list il );

赋值内容
赋值ump(或il)作为容器的新内容。

在调用之前包含在对象中的元素被销毁,并被unordered_map ump或初始化器列表il中的元素替换(如果有的话)。
第一个版本(1)执行一个复制赋值,它将ump的所有元素复制到容器对象中(ump保留其内容)。
第二个版本(2)执行移动分配,将ump内容的所有权转移给对象。没有赋值发生:内容被ump丢弃。
第三个版本(3)将初始化器列表il的内容赋值为容器对象的元素。

参数:

ump:
有着相同类型的unordered_map对象(有着相同的模版参数)
il:
一个initializer_list对象。编译器将从初始化器列表声明器自动构造这些对象。

成员类型value_type是unordered_map中包含的元素的类型,它是pair,其中成员类型key_type是第一个模板参数(key类型)的别名,而mapped_type是第二个模板参数(mapped映射类型,T)的别名。
返回值:
*this
举例:
#include 
#include <string>
#include 
using namespace std;

using stringmap = unordered_map<string, string>;

stringmap merge(stringmap a, stringmap b){
    stringmap temp{a};
    temp.insert(b.begin(), b.end());
    return temp;
}

int main(){
    stringmap first, second, third;
    first = {{"AAPL","Apple"},{"MSFT","Microsoft"}}; //初始化列表
    second = {{"GOOG", "Google"}, {"ORCL", "Oracle"}};
    third = merge(first, second);
    first = third;

    cout << "first contains : ";
    for(auto& x:first) cout << "  " << x.first << ":" << x.second;
    cout << endl;
    return 0;
}

返回:

first contains :   GOOG:Google  ORCL:Oracle  MSFT:Microsoft  AAPL:Apple

 

Capacity容量

4)empty

bool empty() const noexcept;

测试容器是否为空
返回一个bool值,该值指示unordered_map容器是否为空,即其大小是否为0。

此函数不以任何方式修改容器的内容。要清除数组对象的内容,成员函数unordered_map::clear是存在的。

参数:

none

返回值:

如果容器大小为0则返回true,否则返回false

举例:

#include 
#include 
using namespace std;

int main(){
    unordered_map<int, int> first;
    unordered_map<int, int> second = {{1,10},{2,20},{3,30}};
    cout << "first " << (first.empty()?"is empty":"is not empty") << endl;
    cout << "second " << (second.empty()? "is empty" : "is not empty") << endl;
    return 0;
}

返回:

first is empty
second is not empty

 

5)size

size_type size() const noexcept;

返回容器大小
返回unordered_map容器中的元素数量。

参数:

none

返回值:

容器中元素的数量。
成员类型size_type是无符号整数类型。

举例:

#include 
#include <string>
#include 
using namespace std;

int main(){
    unordered_map<string,double> mymap ={
            {"milk", 2.30},
            {"potatoes", 1.90},
            {"eggs", 0.40}
    };
    cout << "mymap.size() is " << mymap.size() << endl;
    return 0;
}

返回:

mymap.size() is 3

 

6)max_size

size_type max_size() const noexcept;

返回最大大小
返回unordered_map容器可以容纳的元素的最大数量。

这是由于系统约束或其库实现的限制,容器所能容纳的最大潜在元素数。

参数:
none

返回值:

对象可以作为内容容纳的元素的最大数目。
成员类型size_type是无符号整数类型。

举例:

#include 
#include 
using namespace std;

int main(){
    unordered_map<int,int> mymap;
    cout << "max_size = " << mymap.max_size() << endl;
    cout << "max_bucket_count = " << mymap.max_bucket_count() << endl;
    cout << "max_load_factor = " << mymap.max_load_factor() << endl;
    return 0;
}

返回:

max_size = 768614336404564650
max_bucket_count = 768614336404564650
max_load_factor = 1

 

Iterators迭代器

7)begin

container iterator (1)    
      iterator begin() noexcept;
const_iterator begin() const noexcept;

bucket iterator (
2) local_iterator begin ( size_type n ); const_local_iterator begin ( size_type n ) const;

返回迭代器开始
返回一个迭代器,该迭代器指向unordered_map容器(1)或其中一个桶(2)中的第一个元素。

注意,unordered_map对象不能保证哪个特定的元素被认为是它的第一个元素。但是,在任何情况下,从开始到结束的范围覆盖容器(或桶)中的所有元素,直到失效。

参数:

n:

桶数。这应该小于bucket_count。
它是一个可选参数,可以改变这个成员函数的行为:如果设置,迭代器将检索到该桶的第一个元素,否则它将指向容器的第一个元素。
成员类型size_type是无符号整数类型。

返回值:

容器(1)或桶(2)中的第一个元素的迭代器。

所有返回类型(iterator、const_iterator、local_iterator和const_local_iterator)都是成员类型。在unordered_map类模板中,这些是正向迭代器类型。
局部迭代器与非局部迭代器属于同一类别。它们的value_type、diffence_type、指针和引用成员类型也是相同的。但是迭代器本身不一定是相同类型的。

 

8)end

container iterator (1)    
      iterator end() noexcept;
const_iterator end() const noexcept;

bucket iterator (
2) local_iterator end (size_type n); const_local_iterator end (size_type n) const;

返回迭代器终点
返回一个迭代器,该迭代器指向unordered_map容器(1)或其中一个桶(2)中的past-the-end元素。

end返回的迭代器不指向任何元素,而是指向unordered_map容器中最后一个元素后面的位置(它的结束位置)。因此,返回的值不能取消引用——它通常用于描述一个范围的开放端,比如[begin,end]。
注意,unordered_map对象并不保证其元素的顺序。但是,在任何情况下,从开始到结束的范围覆盖容器(或桶)中的所有元素,直到失效。

参数:

n:

桶数。这应该小于bucket_count。
它是一个可选参数,可以改变这个成员函数的行为:如果设置,迭代器将检索到该桶的第一个元素,否则它将指向容器的第一个元素。
成员类型size_type是无符号整数类型。

返回值:

元素的迭代器,遍历容器(1)或桶(2)的末端。

所有返回类型(iterator、const_iterator、local_iterator和const_local_iterator)都是成员类型。在unordered_map类模板中,这些是正向迭代器类型。
局部迭代器与非局部迭代器属于同一类别。它们的value_type、diffence_type、指针和引用成员类型也是相同的。但是迭代器本身不一定是相同类型的。

 

举例:

#include 
#include <string>
#include 
using namespace std;

int main(){
    unordered_map<string, string> mymap;
    mymap = {{"Australia", "canberra"}, {"U.S.", "Washington"}, {"France", "Paris"}};
    cout << "mymap contains : ";
    for(auto it = mymap.begin(); it!=mymap.end(); ++it)
        cout << "  " << it->first << " : " << it->second;
    cout << endl;

    cout << "mymap's buckets contains: \n";
    for(unsigned i = 0; ii){
        cout << "bucket #" << i << " contains : ";
        for(auto local_it = mymap.begin(i); local_it!=mymap.end(i); ++local_it)
            cout << "  " <first << " : " << local_it->second;
        cout << endl;
    }
    return 0;
}

返回:

mymap contains :   France : Paris  U.S. : Washington  Australia : canberra
mymap's buckets contains: 
bucket #0 contains : 
bucket #1 contains : 
bucket #2 contains :   France : Paris
bucket #3 contains :   U.S. : Washington  Australia : canberra
bucket #4 contains : 

 

9)cbegin

container iterator (1)    
const_iterator cbegin() const noexcept;

bucket iterator (
2) const_local_iterator cbegin ( size_type n ) const;

返回const_iterator起点
返回一个const_iterator,指向unordered_map容器(1)或其中一个桶(2)中的第一个元素。

常量迭代器是指向const内容的迭代器。这个迭代器可以增加或减少(除非它本身也是const),就像unordered_map::begin返回的迭代器一样,但是它不能用来修改它所指向的内容

参数:

n:

桶数。这应该小于bucket_count。
它是一个可选参数,可以改变这个成员函数的行为:如果设置,迭代器将检索到该桶的第一个元素,否则它将指向容器的第一个元素。
成员类型size_type是无符号整数类型。

返回值:

容器(1)或桶(2)中的第一个元素的迭代器。

 

const_iterator和const_local_iterator都是成员类型。在unordered_map类模板中,这些是正向迭代器类型。
const_local_iterator是与const_iterator相同类别的interator。它们的value_type、diffence_type、指针和引用成员类型也是相同的。但是迭代器本身不一定是相同类型的。

 

10)cend

container iterator (1)    
const_iterator cend() const noexcept;

bucket iterator (
2) const_local_iterator cend ( size_type n ) const;

返回const_iterator结尾
返回一个const_iterator,指向unordered_map容器(1)或其中一个桶(2)中的past-the-end元素。

cend返回的const_iterator不指向任何元素,而是指向unordered_map容器中最后一个元素之后的位置(past-the-end),或者它的一个bucket(即,past-the-end的位置)。因此,返回的值不能取消引用——它通常用于描述范围的开放端,比如[cbegin,cend)。

注意,unordered_map对象并不保证其元素的顺序。但是,在任何情况下,从cbegin到cend的范围覆盖容器(或bucket)中的所有元素,直到失效。

const_iterator是指向const内容的迭代器。这个迭代器可以增加或减少(除非它本身也是const),就像unordered_map::end返回的迭代器一样,但是它不能用来修改它所指向的内容。

参数:

n:

桶数。这应该小于bucket_count。
它是一个可选参数,可以改变这个成员函数的行为:如果设置,迭代器将检索到该桶的第一个元素,否则它将指向容器的第一个元素。
成员类型size_type是无符号整数类型。

返回值:

元素的迭代器,遍历容器(1)或桶(2)的末端。

const_iterator和const_local_iterator都是成员类型。在unordered_map类模板中,这些是正向迭代器类型。
const_local_iterator是与const_iterator相同类别的interator。它们的value_type、diffence_type、指针和引用成员类型也是相同的。但是迭代器本身不一定是相同类型的。

 

举例:

#include 
#include <string>
#include 
using namespace std;

int main(){
    unordered_map<string, string> mymap;
    mymap = {{"Australia", "canberra"}, {"U.S.", "Washington"}, {"France", "Paris"}};

    cout << "mymap contains : ";
    for(auto it = mymap.cbegin(); it!=mymap.cend(); ++it)
        cout << "  " << it->first << " : " << it->second;
    cout << endl;

    cout << "mymap's buckets contains: \n";
    for(unsigned i = 0; ii){
        cout << "bucket #" << i << " contains : ";
        for(auto local_it = mymap.cbegin(i); local_it!=mymap.cend(i); ++local_it)
            cout << "  " <first << " : " << local_it->second;
        cout << endl;
    }
    return 0;
}

返回:

mymap contains :   France : Paris  U.S. : Washington  Australia : canberra
mymap's buckets contains: 
bucket #0 contains : 
bucket #1 contains : 
bucket #2 contains :   France : Paris
bucket #3 contains :   U.S. : Washington  Australia : canberra
bucket #4 contains : 

 

Element access元素访问

11)operator[]

mapped_type& operator[] ( const key_type& k );
mapped_type& operator[] ( key_type&& k );

访问元素
如果k匹配容器中元素的键,则该函数返回对其映射值的引用。

如果k不匹配容器中任何元素的键,则该函数用该键插入一个新元素并返回对其映射值的引用。请注意,即使没有将映射值分配给元素(元素是使用其默认构造函数构造的),这也总是将容器大小增加1。
类似的成员函数unordered_map::at在具有键的元素存在时具有相同的行为,但在元素不存在时抛出异常。

参数:

k:

要访问其映射值的元素的键值。
成员类型key_type是存储在容器中的元素的键的类型,在unordered_map中定义为其第一个模板参数(键key)的别名。
如果是rvalue(第二个版本,右值引用),则在插入新元素时移动键而不是复制键

返回值:

对元素的映射值的引用,其键值等效于k。
成员类型mapped_type是容器中映射值的类型,在unordered_map中定义为其第二个模板参数(T)的别名。

如果插入了新元素,则使用allocator_traits::construct()分配它的存储,这可能会在失败时抛出异常(对于默认分配器,如果分配请求没有成功,则抛出bad_alloc)。

举例:

#include 
#include <string>
#include 
using namespace std;


int main(){
    unordered_map<string, string> mymap;
    mymap["Bakery"] = "Barbara";
    mymap["Seafood"] = "Lisa";
    mymap["Produce"] = "John";

    string name = mymap["Bakery"];
    mymap["Seafood"] = name;

    mymap["Bakery"] = mymap["Produce"];
    name = mymap["Deli"];

    mymap["Produce"] = mymap["Gifts"];

    for(auto& x:mymap)
        cout << x.first << ": " << x.second << endl;

    return 0;
}

返回:

Deli: 
Produce: 
Gifts: 
Seafood: Barbara
Bakery: John

 

12)at

mapped_type& at ( const key_type& k );
const mapped_type& at ( const key_type& k ) const;

访问元素
返回对unordered_map中键为k的元素的映射值的引用。
如果k不匹配容器中任何元素的键,该函数将抛出out_of_range异常。

参数:

k:

要访问其映射值的元素的键值。
成员类型key_type是存储在容器中的元素的键的类型,在unordered_map中定义为其第一个模板参数(键key)的别名。

返回值:

对元素的映射值的引用,其键值等效于k。
成员类型mapped_type是容器中映射值的类型,在unordered_map中定义为其第二个模板参数(T)的别名。

 

举例:

#include 
#include <string>
#include 
using namespace std;

int main(){
    unordered_map<string, int> mymap = {
            {"Mars", 3000},
            {"Saturn", 60000},
            {"Jupiter", 70000}
    };
    mymap.at("Mars") = 3396;
    mymap.at("Saturn") += 272;
    mymap.at("Jupiter") = mymap.at("Saturn") + 9638;

    for(auto& x : mymap){
        cout << x.first << ": " << x.second << endl;
    }
    return 0;
}

返回:

Jupiter: 69910
Saturn: 60272
Mars: 3396

 

Element lookup元素查看

13)find

iterator find ( const key_type& k );
const_iterator find ( const key_type& k ) const;

获取元素的iterator
在容器中搜索以k为键的元素,如果找到了,就返回一个迭代器,否则就返回unordered_map::end(容器末尾的元素)的迭代器。

另一个成员函数unordered_map::count可用于检查特定键是否存在。
还可以使用at或操作符[]的成员函数直接访问映射值。

参数:

k:

要搜索的建值key。
成员类型key_type是容器中元素的键的类型,在unordered_map中定义为其第一个模板参数(key键)的别名。

返回值:

元素的迭代器(如果找到指定的键值),或者unordered_map::end(如果在容器中没有找到指定的键)。
成员类型iterator和const_iterator是前向迭代器类型。

举例:

#include 
#include <string>
#include 
using namespace std;


int main(){
    unordered_map<string, double> mymap = {
            {"mom", 5.4},
            {"dad", 6.1},
            {"bro", 5.9}
    };
    string input;
    cout << "who?";
    getline(cin, input);
    unordered_map<string, double>::const_iterator got = mymap.find(input);

    if(got == mymap.end())
        cout << "not found";
    else
        cout << got->first << " is " << got->second;
    cout << endl;
    return 0;
}

返回:

who?mom
mom is 5.4

 

14)count

size_type count ( const key_type& k ) const;

用特定的键对元素计数
在容器中搜索键为k的元素,并返回找到的元素数量。因为unordered_map容器不允许重复的键,这意味着如果容器中存在具有该键的元素,则该函数实际返回1,否则返回0

参数:

k:

要搜索的建值key。
成员类型key_type是容器中元素的键的类型,在unordered_map中定义为其第一个模板参数(key键)的别名。

返回值:

如果找到键值等于k的元素,则为1,否则为0。

成员类型size_type是无符号整数类型。

举例:

#include 
#include <string>
#include 
using namespace std;

int main(){
    unordered_map<string, double> mymap = {
            {"Burger", 2.99},
            {"Fries", 1.99},
            {"Soda", 1.50}
    };

    for(auto& x : {"Burger", "Pizza", "Salad", "Soda"}){
        if(mymap.count(x) > 0){
            cout << "mymap has " << x << endl;
        }else{
            cout << "mymap has no " << x << endl;
        }
    }
    return 0;
}

返回:

mymap has Burger
mymap has no Pizza
mymap has no Salad
mymap has Soda

 

15)equal_range

pair
   equal_range ( const key_type& k );
pair
   equal_range ( const key_type& k ) const;

获取具有特定键值的元素范围
返回一个范围的边界,该范围包含容器中所有的元素,其中键的值与k相比较。在unordered_map容器中,键是惟一的,该范围最多包含一个元素。

如果k与容器中的任何键不匹配,则返回的范围将end作为其上下范围边界。

参数:

k:

要搜索的建值key。
成员类型key_type是容器中元素的键的类型,在unordered_map中定义为其第一个模板参数(key键)的别名。

返回值:

函数返回一个对pair,其中它的成员pair::first是指向范围下界的迭代器,pair::second是指向其上界的迭代器。范围内的元素是这两个迭代器之间的元素,包括pair::first,而不包括pair::second。

成员类型iterator和const_iterator是前向迭代器类型。

举例:

#include 
#include <string>
#include 
#include 
using namespace std;

using stringmap = unordered_map<string, string>;


int main(){
    stringmap myumm = {
            {"orange", "FL"},
            {"strawberry", "LA"},
            {"strawberry", "OK"},
            {"pumpkin", "NH"}
    };
    cout << "Entries with strawberry : ";
    auto range = myumm.equal_range("strawberry");
    for_each(
            range.first,
            range.second,
            [](stringmap::value_type& x){cout << " " << x.second;}
            );
    return 0;
}

返回:

Entries with strawberry :  LA

如果使用的是unordered_multimap:

#include 
#include <string>
#include 
#include 
using namespace std;

using stringmap = unordered_multimap<string, string>;

stringmap merge(stringmap a, stringmap b){
    stringmap temp{a};
    temp.insert(b.begin(), b.end());
    return temp;
}

int main(){
    stringmap myumm = {
            {"orange", "FL"},
            {"strawberry", "LA"},
            {"strawberry", "OK"},
            {"pumpkin", "NH"}
    };
    cout << "Entries with strawberry : ";
    auto range = myumm.equal_range("strawberry");
    for_each(
            range.first,
            range.second,
            [](stringmap::value_type& x){cout << " " << x.second;}
            );
    return 0;
}

返回:

Entries with strawberry :  LA OK

 

Modifiers修改

16)emplace-如果该建值已有则不操作

template <class... Args>
pairbool> emplace ( Args&&... args );

构造和插入元素
如果unordered_map的键是惟一的,则在该元素中插入一个新元素。使用args作为元素构造函数的参数构造这个新元素。

只有在容器中没有与被放置的键等价的键时才进行插入(unordered_map中的键是惟一的)。

如果插入,这将有效地将容器大小增加1。
存在一个类似的成员函数insert,它复制或将现有对象移动到容器中。

参数:

args:

参数,用于为插入的元素构造映射类型的新对象。

返回值:

如果发生插入的情况(因为不存在具有相同键值的其他元素),函数将返回一个pair对象,该对象的第一个组件是插入元素的迭代器,第二个组件为true。

否则,返回的pair对象的第一个组件是一个迭代器,它指向容器中具有相同键的元素,第二个组件是false。
成员类型迭代器是正向迭代器类型。

新元素的存储是使用allocator_traits::construct()分配的,它可能会在失败时抛出异常(对于默认的分配器,如果分配请求没有成功,就会抛出bad_alloc)。

 

17)emplace_hint

template <class... Args> iterator emplace_hint ( const_iterator position, Args&&... args );

使用提示来构造和插入元素
如果unordered_map的键是惟一的,则在该元素中插入一个新元素。使用args作为元素构造函数的参数构造这个新元素。position位置点指向容器中的一个位置,该位置提示从何处开始搜索其插入点(容器可能使用,也可能不使用此建议来优化插入操作)。

只有在容器中没有与被放置的键等价的键时才进行插入(unordered_map中的键是惟一的)。
如果插入,这将有效地将容器大小增加1。

类似的成员函数insert也存在,它可以复制或将现有对象移动到容器中,也可以获取位置提示。

参数:

position:

作为插入操作提示的位置。容器可以使用这个值来优化操作。
成员类型const_iterator是正向迭代器类型。

args:

参数,用于为插入的元素构造映射类型的新对象。

返回值:

容器中元素的迭代器,其键相当于新插入的元素。如果确实插入了新插入的元素,那么它将指向该元素;如果已经存在键,则指向具有等效键的现有元素(不替换它)。

成员类型迭代器是一个前向迭代器。
新元素的存储是使用allocator_traits::construct()分配的,它可能会在失败时抛出异常(对于默认的分配器,如果分配请求没有成功,就会抛出bad_alloc)。

 

举例:

#include 
#include <string>
#include 
#include 
using namespace std;

int main(){
    unordered_map<string,string> mymap;
    mymap.emplace("NCC-1701", "J.T. Kirk");
    mymap.emplace("NCC-1701-D", "J.L. Picard");
    mymap.emplace("NCC-74656", "K. Janeway");
    mymap.emplace("NCC-1701", "new J.T. Kirk");

    cout << "mymap contains : " << endl;
    for(auto& x:mymap)
        cout << x.first << ": " << x.second << endl;
    cout << endl;
    return 0;
}

返回:

NCC-74656: K. Janeway
NCC-1701-D: J.L. Picard
NCC-1701: J.T. Kirk

 

18)insert-可同时插入多个

(1)    
pairbool> insert ( const value_type& val );

(
2) template <class P> pairbool> 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 il );

插入元素
在unordered_map中插入新元素。

只有当每个元素的键不等于容器中已经存在的任何其他元素的键时,才会插入元素(unordered_map中的键是惟一的)。
这实际上增加了插入元素的数量,从而增加了容器的大小。
这些参数决定了插入了多少个元素,并将它们初始化为哪些值:

参数:

val:
对象复制到新元素的值(或作为新元素的值移动)。

版本(1)和(3)复制元素(即val保存它的内容,容器保存一个副本)。

版本(2)和(4)移动元素(即 val将丢失它的内容,它将被容器中的新元素获取)。

成员类型value_type是容器中元素的类型,在unordered_map中定义为对,其中成员类型key_type是第一个模板参数(key类型)的别名,而mapped_type是第二个模板参数(mapped映射类型,T)的别名。
只有当P是隐式转换为value_type的类型时,才调用带有P&&类型参数的签名。
hint:
迭代器到建议的位置,作为从何处开始搜索合适的插入点的提示。容器可能使用这个值,也可能不使用它来优化操作。元素将存储在其相应的bucket中,而不管作为提示传递的是什么。

成员类型const_iterator是正向迭代器类型。

first, last:
指定元素范围的迭代器。将[first,last)范围内的元素的副本插入到unordered_map容器中。

注意,范围包括first和last之间的所有元素,包括first指向的元素,但不包括last指向的元素。

第一个和最后一个都不是目标容器中的迭代器。

模板类型可以是任何类型的输入迭代器。
il:
一个initializer_list对象。编译器将从初始化器列表声明器自动构造这些对象。

成员类型value_type容器中包含的元素的类型,定义在unordered_map一pair< key_type const, mapped_type >,成员类型相关联是一个别名的第一个模板参数(key键类型),和mapped_type别名的第二个模板参数(mapped映射类型,T)。
返回值:
在版本(1)和(2)中,函数返回一个pair对象,该对象的第一个元素是一个迭代器,它指向容器中新插入的元素或键值相等的元素,并返回一个bool值,该值指示元素是否被成功插入。

在版本(3)和(4)中,函数返回一个迭代器,它要么指向容器中新插入的元素,要么指向键相同的元素。

版本(5)和(6)没有返回任何值。

成员类型迭代器是正向迭代器类型。

新元素的存储是使用allocator_traits::construct()分配的,它可能会在失败时抛出异常(对于默认的分配器,如果分配请求没有成功,就会抛出bad_alloc)。

举例:
#include 
#include <string>
#include 
#include 
using namespace std;

int main(){
    unordered_map<string, double>
            myrecipe,
            mypantry = {{"milk", 2.0}, {"flour", 1.5}};
    pair<string, double> myshopping("barking powder", 0.3);

    myrecipe.insert(myshopping);
    myrecipe.insert(make_pair<string, double>("egg", 6.0));
    myrecipe.insert({{"suger", 0.8},{"salt", 0.1}});

    cout << "myrecipe contains : " << endl;
    for(auto& x : myrecipe)
        cout << x.first <<  "  " << x.second << endl;
    cout << endl;
    return 0;
}

返回:

myrecipe contains : 
suger  0.8
egg  6
salt  0.1
barking powder  0.3

 

19)erase

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 );

删除元素
从unordered_map容器中删除单个元素或一组元素([first,last])。

通过调用每个元素的析构函数,可以通过删除的元素数量有效地减少容器的大小。

参数:

position:

指向要从unordered_map中删除的单个元素的迭代器。
成员类型const_iterator是正向迭代器类型。

k:

要删除的建值key。
成员类型key_type是容器中元素的键的类型,在unordered_map中定义为其第一个模板参数(key键)的别名。

first, last:
迭代器在unordered_map容器中指定要删除的范围:[first,last)。即范围包括first和last之间的所有元素,包括first指向的元素,但不包括last指向的元素。

注意,unordered_map容器并不遵循任何特定的顺序来组织它的元素,
因此range删除的效果可能不太容易预测

成员类型const_iterator是正向迭代器类型。
返回值:
版本(1)和(3)返回一个迭代器,指向被擦除的最后一个元素之后的位置。

Version(2)返回被擦除的元素的数量,在unordered_map容器中(具有惟一键),如果存在键值为k的元素(因此随后被擦除),则为1,否则为0。

成员类型迭代器是正向迭代器类型。

成员类型size_type是无符号整数类型。

举例:
#include 
#include <string>
#include 
#include 
using namespace std;

int main(){
    unordered_map<string, string> mymap;
    // populating container:
    mymap["U.S."] = "Washington";
    mymap["U.K."] = "London";
    mymap["France"] = "Paris";
    mymap["Russia"] = "Moscow";
    mymap["China"] = "Beijing";
    mymap["Germany"] = "Berlin";
    mymap["Japan"] = "Tokyo";
    for(auto& x:mymap)
        cout << x.first << "  " << x.second << endl;
    cout << endl;
    
    mymap.erase(mymap.begin());
    for(auto& x:mymap)
        cout << x.first << "  " << x.second << endl;
    cout << endl;

    mymap.erase("France");
    for(auto& x:mymap)
        cout << x.first << "  " << x.second << endl;
    cout << endl;

    mymap.erase(mymap.find("U.S."), mymap.end());

    for(auto& x:mymap)
        cout << x.first << "  " << x.second << endl;
    cout << endl;
    return 0;
}

返回:

/Users/user/CLionProjects/untitled/cmake-build-debug/untitled
Japan  Tokyo
China  Beijing
U.S.  Washington
Russia  Moscow
Germany  Berlin
France  Paris
U.K.  London

China  Beijing
U.S.  Washington
Russia  Moscow
Germany  Berlin
France  Paris
U.K.  London

China  Beijing
U.S.  Washington
Russia  Moscow
Germany  Berlin
U.K.  London

China  Beijing


Process finished with exit code 0

 

20)clear

void clear() noexcept;

清除内容
将删除unordered_map容器中的所有元素:调用它们的析构函数,并从容器中删除它们,使其大小为0。

参数:

none

返回值:
none

举例:

#include 
#include <string>
#include 
#include 
using namespace std;


int main(){
    unordered_map<string,string> mymap =
            { {"house","maison"}, {"car","voiture"}, {"grapefruit","pamplemousse"} };
    cout << "mymap contains : ";
    for(auto& x : mymap) cout << "  " << x.first << "=" << x.second;
    cout << endl;

    mymap.clear();
    mymap["hello"]="bonjour";
    mymap["sun"]="soleil";

    cout << "mymap contains : ";
    for(auto& x : mymap) cout << "  " << x.first << "=" << x.second;
    cout << endl;
    return 0;
}

返回:

mymap contains :   grapefruit=pamplemousse  car=voiture  house=maison
mymap contains :   sun=soleil  hello=bonjour

 

21)swap

void swap ( unordered_map& ump );

交换内容
通过ump的内容交换容器的内容,ump是另一个包含相同类型元素的unordered_map对象。大小可能不同。

在调用这个成员函数之后,这个容器中的元素是在调用之前在ump中的元素,而ump中的元素是在这个容器中的元素。容器内部保存的其他对象(例如它们的hasher或key_equal对象)也被交换。

该函数在容器之间交换指向数据的内部指针,而不实际执行任何副本或对单个元素进行移动,因此无论大小,执行时间都是恒定的。
注意,全局算法函数的名称是swap。为使unordered_map类型的参数具有与此成员函数相同的行为和复杂性,将重载此全局函数。

参数:

ump:

另一个与此类型相同的unordered_map容器对象。

返回值:

none

举例:

#include 
#include <string>
#include 
#include 
using namespace std;


int main(){
    unordered_mapstring,std::string>
            first = {{"Star Wars","G. Lucas"},{"Alien","R. Scott"},{"Terminator","J. Cameron"}},
            second  = {{"Inception","C. Nolan"},{"Donnie Darko","R. Kelly"}};
    cout << "first contains : ";
    for(auto& x : first) cout << "  " << x.first << "=" << x.second;
    cout << endl;

    cout << "second contains : ";
    for(auto& x : second) cout << "  " << x.first << "=" << x.second;
    cout << endl;

    first.swap(second);
    
    cout << "first contains : ";
    for(auto& x : first) cout << "  " << x.first << "=" << x.second;
    cout << endl;

    cout << "second contains : ";
    for(auto& x : second) cout << "  " << x.first << "=" << x.second;
    cout << endl;
    return 0;
}

返回:

first contains :   Terminator=J. Cameron  Alien=R. Scott  Star Wars=G. Lucas
second contains :   Donnie Darko=R. Kelly  Inception=C. Nolan
first contains :   Donnie Darko=R. Kelly  Inception=C. Nolan
second contains :   Terminator=J. Cameron  Alien=R. Scott  Star Wars=G. Lucas

 

Buckets桶

22)bucket_count

size_type bucket_count() const noexcept;

桶数
返回unordered_map容器中的桶数。

bucket是容器内部哈希表中的一个槽,根据键的哈希值将元素赋给它。
桶的数量直接影响容器的哈希表的负载因子(从而影响碰撞的概率)。容器会自动增加桶的数量,以使负载因子低于特定的阈值(其max_load_factor),从而在每次需要增加桶的数量时重新散列。

参数:

none

返回值:

当前桶的数量。

成员类型size_type是无符号整数类型。

举例:

#include 
#include <string>
#include 
#include 
using namespace std;

using stringmap = unordered_map<string, string>;

stringmap merge(stringmap a, stringmap b){
    stringmap temp{a};
    temp.insert(b.begin(), b.end());
    return temp;
}

int main(){
    unordered_map<string,string> mymap = {
            {"house","maison"},
            {"apple","pomme"},
            {"tree","arbre"},
            {"book","livre"},
            {"door","porte"},
            {"grapefruit","pamplemousse"}
    };

    unsigned n = mymap.bucket_count();

    std::cout << "mymap has " << n << " buckets.\n";

    for (unsigned i=0; ii) {
        cout << "bucket #" << i << " contains: ";
        for (auto it = mymap.begin(i); it!=mymap.end(i); ++it)
            cout << "[" << it->first << ":" << it->second << "] ";
        cout << "\n";
    }
    return 0;
}

返回:

/Users/user/CLionProjects/untitled/cmake-build-debug/untitled
mymap has 11 buckets.
bucket #0 contains: 
bucket #1 contains: [house:maison] 
bucket #2 contains: 
bucket #3 contains: [tree:arbre] 
bucket #4 contains: 
bucket #5 contains: 
bucket #6 contains: [grapefruit:pamplemousse] [door:porte] 
bucket #7 contains: 
bucket #8 contains: 
bucket #9 contains: 
bucket #10 contains: [apple:pomme] [book:livre] 

Process finished with exit code 0

 

23)max_bucket_count

size_type max_bucket_count() const noexcept;

返回最大桶数
返回unordered_map容器可以拥有的最大桶数。

这是由于系统约束或其库实现的限制,容器可能拥有的最大桶数。

参数:

none

返回值:

最大桶数。

成员类型size_type是无符号整数类型。

举例:

#include 
#include 
using namespace std;

int main(){
    unordered_map<int,int> mymap;

    cout << "max_size = " << mymap.max_size() << endl;
    cout << "max_bucket_count = " << mymap.max_bucket_count() << endl;
    cout << "max_load_factor = " << mymap.max_load_factor() << endl;
    return 0;
}

返回:

max_size = 768614336404564650
max_bucket_count = 768614336404564650
max_load_factor = 1

 

24)bucket_size

size_type bucket_size ( size_type n ) const;

返回桶大小
返回bucket n中元素的数量。

bucket是容器内部哈希表中的一个槽,根据键的哈希值将元素赋给它。

桶中元素的数量影响访问桶中特定元素所需的时间。容器会自动增加桶的数量,以使装载因子(即平均桶大小)低于其max_load_factor。

参数:

n:

桶数。
这应该低于bucket_count。
成员类型size_type是无符号整数类型。

返回值:

桶中元素的数目n。

成员类型size_type是无符号整数类型。

举例:

#include 
#include <string>
#include 
#include 
using namespace std;

int main(){
    unordered_map<string,string> mymap = {
            {"us","United States"},
            {"uk","United Kingdom"},
            {"fr","France"},
            {"de","Germany"}
    };
    unsigned nbuckets = mymap.bucket_count();
    cout << "mymap has " << nbuckets << " buckets : " << endl;

    for(unsigned i = 0; ii)
        cout << "bucket # " << i << " has " << mymap.bucket_size(i) << " elements " << endl;
    return 0;
}

返回:

mymap has 5 buckets : 
bucket # 0 has 1 elements 
bucket # 1 has 0 elements 
bucket # 2 has 0 elements 
bucket # 3 has 1 elements 
bucket # 4 has 2 elements 

 

25)bucket

size_type bucket ( const key_type& k ) const;

定位元素的桶
返回键为k的元素所在的桶号。

bucket是容器内部哈希表中的一个槽,根据键的哈希值将元素赋给它。桶的编号从0到(bucket_count-1)。
可以通过unordered_map::begin和unordered_map::end返回的范围迭代器访问bucket中的各个元素。

参数:

k:

要定位其存储桶的键值key。
成员类型key_type是容器中元素的键的类型,在unordered_map中定义为其第一个模板参数(key键)的别名。

返回值:

对应k的桶序列号

成员类型size_type是无符号整数类型。

举例:

#include 
#include <string>
#include 
using namespace std;


int main(){
    unordered_map<string,string> mymap = {
            {"us","United States"},
            {"uk","United Kingdom"},
            {"fr","France"},
            {"de","Germany"}
    };

    for (auto& x: mymap) {
        cout << "Element [" << x.first << ":" << x.second << "]";
        cout << " is in bucket #" << mymap.bucket (x.first) << endl;
    }
    return 0;
}

返回:

Element [de:Germany] is in bucket #0
Element [fr:France] is in bucket #3
Element [uk:United Kingdom] is in bucket #4
Element [us:United States] is in bucket #4

 

Hash policy

26) load_factor

float load_factor() const noexcept;

返回负载因子
返回unordered_map容器中的当前负载因子。

负载因子是容器中元素的数量(其大小)与桶的数量(bucket_count)之间的比率:
load_factor = size / bucket_count

在哈希表中,负载因素影响碰撞的概率(即两个元素位于同一桶中的概率)。容器会自动增加桶的数量,以将负载因子保持在特定的阈值(其max_load_factor)之下,从而在每次需要扩展时导致重新散列。
要检索或更改此阈值,请使用成员函数max_load_factor。

参数:

none

返回值:

当前的负载因子

举例:

#include 
#include <string> #include  using namespace std; int main(){ unordered_map<string,string> mymap = { {"us","United States"}, {"uk","United Kingdom"}, {"fr","France"}, {"de","Germany"} }; cout << "size = " << mymap.size() << endl; cout << "bucket_count = " << mymap.bucket_count() << endl; cout << "load_factor = " << mymap.load_factor() << endl; cout << "max_load_factor = " << mymap.max_load_factor() << endl; return 0; }

返回:

size = 4 bucket_count = 5 load_factor = 0.8 max_load_factor = 1

 

27)max_load_factor

get (1)    
float max_load_factor() const noexcept;
set (2)    
void max_load_factor ( float z );

获取或设置最大负载因子
第一个版本(1)返回unordered_map容器的当前最大负载因子。
第二个版本(2)将z设置为unordered_map容器的新最大负载因子。

负载因子是容器中元素的数量(其大小)与桶的数量(bucket_count)之间的比率。

默认情况下,unordered_map容器的max_load_factor为1.0

在哈希表中,负载因素影响碰撞的概率。,两个元素位于同一桶中的概率)。容器使用max_load_factor的值作为阈值,该阈值强制增加桶的数量(从而导致重新散列)。
但是请注意,该实现可能会对桶的数量施加上限(请参阅max_bucket_count),这可能会迫使容器忽略max_load_factor。

参数:

z:

新的最大负载因子

返回值:

当前的负载因子(仅对第一个get版本)

举例:

#include 
#include <string>
#include 
using namespace std;

int main(){
    unordered_map<string,string> mymap = {
            {"Au","gold"},
            {"Ag","Silver"},
            {"Cu","Copper"},
            {"Pt","Platinum"}
    };

    cout << "current max_load_factor: " << mymap.max_load_factor() << endl;
    cout << "current size: " << mymap.size() << endl;
    cout << "current bucket_count: " << mymap.bucket_count() << endl;
    cout << "current load_factor: " << mymap.load_factor() << endl;

    float z = mymap.max_load_factor();
    mymap.max_load_factor ( z / 2.0 ); //小于当前的负载因子则设为当前的,即为0.8,而不是0.5
    cout << "[max_load_factor halved]" << endl;

    cout << endl;
    cout << "new max_load_factor: " << mymap.max_load_factor() << endl;
    cout << "new size: " << mymap.size() << endl;
    cout << "new bucket_count: " << mymap.bucket_count() << endl;
    cout << "new load_factor: " << mymap.load_factor() << endl;

    mymap.max_load_factor ( 0.9 );
    cout << endl;
    cout << "new max_load_factor: " << mymap.max_load_factor() << endl;
    cout << "new size: " << mymap.size() << endl;
    cout << "new bucket_count: " << mymap.bucket_count() << endl;
    cout << "new load_factor: " << mymap.load_factor() << endl;

    return 0;
}

返回:

/Users/user/CLionProjects/untitled/cmake-build-debug/untitled
current max_load_factor: 1
current size: 4
current bucket_count: 5
current load_factor: 0.8
[max_load_factor halved]

new max_load_factor: 0.8
new size: 4
new bucket_count: 5
new load_factor: 0.8

new max_load_factor: 0.9
new size: 4
new bucket_count: 5
new load_factor: 0.8

Process finished with exit code 0

 

28)rehash

void rehash( size_type n );

设置桶数
将容器中的桶数设置为n或更多。

如果n大于容器中当前桶的数量(bucket_count),则强制重新散列。新的bucket count可以等于或大于n。
如果n小于容器中桶的当前数量(bucket_count),则该函数可能对桶数没有影响,也可能不会强制重新散列。

rehash是对哈希表的重构:容器中的所有元素根据它们的哈希值重新排列到新的bucket集合中。这可能会改变容器内元素迭代的顺序。

每当容器的负载因子在操作中超过max_load_factor时,容器就会自动执行重列

注意,这个函数的参数是桶的数量。存在一个类似的函数unordered_map::reserve,它期望容器中的元素数量作为参数。

参数:

n:

容器哈希表的最小桶数。
成员类型size_type是无符号整数类型。

返回值:

none

举例:

#include 
#include <string>
#include 
using namespace std;


int main(){
    unordered_map<string,string> mymap;
    cout << "current bucket_count: " << mymap.bucket_count() << endl;

    mymap.rehash(20);

    mymap["house"] = "maison";
    mymap["apple"] = "pomme";
    mymap["tree"] = "arbre";
    mymap["book"] = "livre";
    mymap["door"] = "porte";
    mymap["grapefruit"] = "pamplemousse";

    cout << "current bucket_count: " << mymap.bucket_count() << endl;

    return 0;
}

返回:

current bucket_count: 0
current bucket_count: 23 //结果可能大于或等于20

 

29)reserve

void reserve ( size_type n );

请求更改每个桶的容量
将容器中的桶数(bucket_count)设置为最适合包含至少n个元素。

如果n大于当前的bucket_count乘以max_load_factor,则容器的bucket_count将增加,并强制重新散列。
如果n小于这个值,函数可能没有作用。

参数:

n:

所要求的元素数量为最小容量。
成员类型size_type是无符号整数类型

举例:

#include 
#include <string>
#include 
#include 
using namespace std;

int main(){
    unordered_map<string,string> mymap;
    mymap["house"] = "maison";
    mymap["apple"] = "pomme";
    mymap["tree"] = "arbre";
    mymap["book"] = "livre";
    mymap["door"] = "porte";
    mymap["grapefruit"] = "pamplemousse";

    cout << "current bucket_count: " << mymap.bucket_count() << endl;
    cout << "current max_load_factor: " << mymap.max_load_factor() << endl;
    for(unsigned i = 0; ii)
        cout << "current bucket_size: " << mymap.bucket_size(i) << endl;

    mymap.reserve(6); //n小于bucket_count*max_load_factor时
    for (auto& x: mymap) {
        std::cout << x.first << ": " << x.second << std::endl;
    }
    cout << "current bucket_count: " << mymap.bucket_count() << endl;
    cout << "current max_load_factor: " << mymap.max_load_factor() << endl;
    for(unsigned i = 0; ii)
        cout << "current bucket_size: " << mymap.bucket_size(i) << endl;

    mymap.reserve(15);//n大于bucket_count*max_load_factor时
    for (auto& x: mymap) {
        std::cout << x.first << ": " << x.second << std::endl;
    }
    cout << "current bucket_count: " << mymap.bucket_count() << endl;
    cout << "current max_load_factor: " << mymap.max_load_factor() << endl;
    for(unsigned i = 0; ii)
        cout << "current bucket_size: " << mymap.bucket_size(i) << endl;

    return 0;
}

返回:

/Users/user/CLionProjects/untitled/cmake-build-debug/untitled
current bucket_count: 11
current max_load_factor: 1
current bucket_size: 0
current bucket_size: 1
current bucket_size: 0
current bucket_size: 1
current bucket_size: 0
current bucket_size: 0
current bucket_size: 2
current bucket_size: 0
current bucket_size: 0
current bucket_size: 0
current bucket_size: 2
apple: pomme
book: livre
tree: arbre
house: maison
grapefruit: pamplemousse
door: porte
current bucket_count: 7
current max_load_factor: 1
current bucket_size: 0
current bucket_size: 1
current bucket_size: 1
current bucket_size: 2
current bucket_size: 0
current bucket_size: 1
current bucket_size: 1
apple: pomme
grapefruit: pamplemousse
book: livre
tree: arbre
house: maison
door: porte
current bucket_count: 17
current max_load_factor: 1
current bucket_size: 0
current bucket_size: 0
current bucket_size: 0
current bucket_size: 0
current bucket_size: 0
current bucket_size: 0
current bucket_size: 0
current bucket_size: 0
current bucket_size: 0
current bucket_size: 2
current bucket_size: 2
current bucket_size: 0
current bucket_size: 0
current bucket_size: 0
current bucket_size: 0
current bucket_size: 1
current bucket_size: 1

Process finished with exit code 0

通过使用unordered_map容器的期望大小(=6)来调用reserve,我们避免了容器大小的增加可能产生的多次重复哈希,并优化了哈希表的大小。

 

Observers

30)hash_function

hasher hash_function() const;

得到哈希函数
返回unordered_map容器使用的散列函数对象。

散列函数是一个一元函数,它接受类型为key_type的对象作为参数,并基于它返回类型为size_t的惟一值。它被构造中的容器所采用(有关更多信息,请参见unordered_map的构造函数unordered_map's constructor)。默认情况下,它是对应键类型的默认哈希函数:hash

参数:

none

返回值:

哈希函数。

成员类型hasher是容器使用的散列函数的类型,在unordered_map中定义为其第三个模板参数(Hash散列)的别名。

举例:

#include 
#include <string>
#include 
using namespace std;

using stringmap = unordered_map<string, string>;

int main(){
    stringmap mymap;

    stringmap::hasher fn = mymap.hash_function();

    //  使用该hash函数求hash值
    cout << "this: " << fn ("this") << endl;
    cout << "thin: " << fn ("thin") << endl;
    return 0;
}

返回:

this: 1610705967341725939
thin: 3142588895646935236

 

31)key_eq

key_equal key_eq() const;

得到键等价谓词
返回unordered_map容器使用的键等价比较谓词。

键等价比较是一个谓词,它接受键类型的两个参数,并返回一个bool值,该值指示是否认为它们是等价的。它被构造中的容器所采用(有关更多信息,请参见unordered_map的构造函数)。默认情况下,它是equal_to,返回的结果与将equal-to操作符(==)应用于参数相同。

参数:

none

返回值:

键相等比较对象。

成员类型key_equal是容器使用的键相等比较谓词的类型,在unordered_map中定义为其第四个模板参数(Pred)的别名。

举例:

#include 
#include <string>
#include 
using namespace std;

int main(){
    unordered_map<string,string> mymap;

    bool case_insensitive = mymap.key_eq()("test","TEST");

    //判断是否大小写敏感
    cout << "mymap.key_eq() is ";
    cout << ( case_insensitive ? "case insensitive" : "case sensitive" );
    cout << endl;
    return 0;
}

返回:

mymap.key_eq() is case sensitive

可见是大小写敏感的,说明返回的是false

 

32)get_allocator

allocator_type get_allocator() const noexcept;

得到分配器
返回用于构造容器的分配器对象。

参数:

none

返回值:
分配器。

成员类型allocator_type是容器使用的分配器的类型,在unordered_map中定义为其第五个模板参数(Alloc)的别名。

 

Non-member function overloads

33)operators

equality (1)    
template <class Key, class T, class Hash, class Pred, class Alloc>
  bool operator== ( const unordered_map& lhs,
                    const unordered_map& rhs );
inequality (2)    
template <class Key, class T, class Hash, class Pred, class Alloc>
  bool operator!= ( const unordered_map& lhs,
                    const unordered_map& rhs );

unordered_map的关系运算符
这些重载的全局操作符函数在unordered_map容器lhs和rhs之间执行适当的相等或不等比较操作。

平等比较的程序如下(如果程序找到一个结论性的答案,则在任何点停止):
首先,比较大小。
然后,在一个容器中查找另一个容器中的每个键,如果找到了,就比较它们的值。

注意,unordered_map::hash_function和unordered_map::key_eq对象在lhs和rhs中具有相同的行为。

参数:

lhs, rhs:
unordered_map容器(分别位于操作符的左侧和右侧),具有相同的模板参数(Key、T、Hash、Pred和Alloc)。
返回值:
相等则返回true,否则为false

举例:

#include 
#include <string>
#include 
using namespace std;

using stringmap = unordered_map<string, string>;

int main(){
    stringmap a = { {"AAPL","Apple"}, {"MSFT","Microsoft"}, {"GOOG","Google"} };
    stringmap b = { {"MSFT","Microsoft"}, {"GOOG","Google"}, {"AAPL","Apple"} };
    stringmap c = { {"MSFT","Microsoft Corp."}, {"GOOG","Google Inc."}, {"AAPL","Apple Inc."} };

    if (a==b) cout << "a and b are equal\n";
    if (b!=c) cout << "b and c are not equal\n";
    return 0;
}

返回:

a and b are equal
b and c are not equal

 

34)swap

template <class Key, class T, class Hash, class Pred, class Alloc>
  void swap ( unordered_map& lhs,
              unordered_map& rhs );

交换两个unordered_map容器的内容
容器lhs的内容与rhs的内容进行交换。两个容器对象必须具有相同的类型(相同的模板参数),尽管大小可能不同。

调用这个函数之后,lhs中的元素是调用之前在rhs中的元素,rhs中的元素是在lhs中的元素。容器内部保存的其他对象(例如它们的hasher或key_equal对象)也被交换。

这是通用算法swap的一种特殊化,它通过交换内部的数据指针来提高性能,而不需要对单个元素执行任何复制或移动。

参数:

lhs, rhs:
unordered_map容器(分别位于操作符的左侧和右侧),具有相同的模板参数(Key、T、Hash、Pred和Alloc)。
返回值:
none

举例:

#include 
#include <string>
#include 
using namespace std;

using stringmap = unordered_map<string, string>;

int main(){
    stringmap
        first = {{"Star Wars","G. Lucas"},{"Alien","R. Scott"},{"Terminator","J. Cameron"}},
        second  = {{"Inception","C. Nolan"},{"Donnie Darko","R. Kelly"}};
    cout << "first: ";
    for (auto& x: first) cout << x.first << " (" << x.second << "), ";
    cout << endl;

    cout << "second: ";
    for (auto& x: second) cout << x.first << " (" << x.second << "), ";
    cout << endl;

    swap(first,second);

    cout << "first: ";
    for (auto& x: first) cout << x.first << " (" << x.second << "), ";
    cout << endl;

    cout << "second: ";
    for (auto& x: second) cout << x.first << " (" << x.second << "), ";
    cout << endl;
    return 0;
}

返回:

first: Terminator (J. Cameron), Alien (R. Scott), Star Wars (G. Lucas), 
second: Donnie Darko (R. Kelly), Inception (C. Nolan), 
first: Donnie Darko (R. Kelly), Inception (C. Nolan), 
second: Terminator (J. Cameron), Alien (R. Scott), Star Wars (G. Lucas),