unordered_map
unordered_map 的介绍文档
unordered_map 的介绍文档:来自cpluscplus.com 的中文翻译
- unordered_map是存储<key, value>键值对的关联式容器,其允许通过keys快速的索引到与
其对应的value。- 在unordered_map中,键值通常用于惟一地标识元素,而映射值是一个对象,其内容与此
键关联。键和映射值的类型可能不同。- 在内部,unordered_map没有对<kye, value>按照任何特定的顺序排序, 为了能在常数范围内
找到key所对应的value,unordered_map将相同哈希值的键值对放在相同的桶中。- unordered_map容器通过key访问单个元素要比map快,但它通常在遍历元素子集的范围迭
代方面效率较低。- unordered_maps实现了直接访问操作符(operator[]),它允许使用key作为参数直接访问
value。- 它的迭代器至少是前向迭代器。
unordered_map
是 C++11 的语法,C++98 是没有 unordered_map
的
构造函数
unordered_map 存储的数据是:key-value 的结构,因此实例化 unordered_map
需要传入两个模板参数。unordered-map
的底层数据结构是哈希表。unordered_map
数据 key-value 形式的存储你可以理解为哈希表存储了一个 pair
。传入的第一个模板参数就是 pair
的 first,传入的第二个模板参数就是 pair
的 second。
- unordered_map 可以无参构造,这是在做算法题用的比较多的。
- unordered_map 可以使用
initializer_list
来初始化。initializer_list
是 C++11 的语法。
#include<iostream>
#include<unordered_map>
using namespace std;
int main()
{
unordered_map<int, int> hash1; //这是无参构造
unordered_map<int, int> hash2({{1,1}, {2,2}, {3,3}}); //这是使用initializer_list来构造
return 0;
}
bool empty() const
这个函数用来判断哈希表是否为空,为空返回 true;否则返回 false。
#include<iostream>
#include<unordered_map>
using namespace std;
int main()
{
unordered_map<int, int> hash1; //这是无参构造
unordered_map<int, int> hash2({{1,1}, {2,2}, {3,3}}); //这是使用initializer_list来构造
cout << hash1.empty() << endl; //输出:1
cout << hash2.empty() << endl; //输出:0
return 0;
}
size_t size() const
这个函数用来获取哈希表中有效元素的个数。
#include<iostream>
#include<unordered_map>
using namespace std;
int main()
{
unordered_map<int, int> hash1; //这是无参构造
unordered_map<int, int> hash2({{1,1}, {2,2}, {3,3}}); //这是使用initializer_list来构造
cout << hash1.size() << endl; //输出:1
cout << hash2.size() << endl; //输出:3
return 0;
}
迭代器
- begin:返回哈希表中第一个元素的位置对应的迭代器。
- end:返回的迭代器并不指向任何元素,而是指向容器中最后一个元素之后的位置。因此,返回的值不应被取消引用。
有了 begin 和 end 迭代器,我们就可以遍历unordered_map
了。
#include<iostream>
#include<unordered_map>
using namespace std;
int main()
{
unordered_map<int, int> hash2({{10,10}, {20,20}, {30,30}}); //这是使用initializer_list来构造
auto it = hash2.begin();
while(it != hash2.end())
{
cout << it->first << " " << it->second << endl;
++it;
}
return 0;
}
我们看到最后遍历得到的结果与插入的顺序并不相同。这也证明了 unordered_map
是一个无序容器。仅仅存储一个 key-value 的数据。
const V& operator[](const K& key)
这个函数和 map
的 operator[]
很像。
如果 key 与容器中某个元素的键相匹配,函数会返回其映射值(value)的引用。
如果 key 与容器中任何元素的键不匹配,函数将插入一个具有该键的新元素,并返回其映射值的引用。请注意,即使没有为元素分配映射值(元素是使用默认构造函数构造的),容器的大小也会增加一个。
#include<iostream>
#include<unordered_map>
using namespace std;
int main()
{
unordered_map<int, int> hash2({{10,10}, {20,20}, {30,30}}); //这是使用initializer_list来构造
cout << hash2[10] << endl; //输出:10
hash2[40]; // 使用 operator[] 访问key为 40 的元素,但是不存在,会插入一个 key 为 40 的元素,value我们没有指定,那么会调用 value 类型的默认构造函数:int() 作为 40 这个 key 值的 value 值
cout << hash2[40] << endl; //输出:0
return 0;
}
iterator find(const K& key)
在 unordered_map
中查找 key,如果查找成功返回该位置对应的迭代器,如果查找失败,那么返回 unordered_map::end
,就是 end 迭代器。
下面的代码中,我们使用 find 查找一个元素,通过得到的迭代器访问他的 value。
#include<iostream>
#include<unordered_map>
using namespace std;
int main()
{
unordered_map<int, int> hash2({{10,10}, {20,20}, {30,30}}); //这是使用initializer_list来构造
auto it = hash2.find(10);
if(it == hash2.end()) cout << "此元素不存在" << endl;
else cout << it->second << endl; //输出:10
return 0;
}
size_t count(const K& key) const
搜索容器中键为 key 的元素,并返回找到的元素个数。由于 unordered_map 容器不允许键重复,这意味着如果容器中存在键为 key 的元素,函数实际返回 1,否则返回 0。
#include<iostream>
#include<unordered_map>
using namespace std;
int main()
{
unordered_map<int, int> hash2({{10,10}, {20,20}, {30,30}}); //这是使用initializer_list来构造
cout << hash2.count(10) << endl; //输出:1
cout << hash2.count(40) << endl; //输出:0
return 0;
}
pair<iterator, bool> insert ( const pair<K, V>& kv )
这个函数和 map
的 insert
完全一样。
你可以向 unordered_map
中插入一个键值对。
函数返回一个 pair 对象,其第一个元素是一个迭代器,指向容器中新插入的元素或键等价的元素,另一个 bool 值表示该元素是否插入成功。
#include<iostream>
#include<unordered_map>
using namespace std;
int main()
{
unordered_map<int, int> hash2({{10,10}, {20,20}, {30,30}}); //这是使用initializer_list来构造
pair<unordered_map<int, int>::iterator, bool> ret1 = hash2.insert(make_pair(40, 40));
cout << "插入成功与否:" << ret1.second << endl; //插入成功,ret1.second 为 1
pair<unordered_map<int, int>::iterator, bool> ret2 = hash2.insert(make_pair(30, 0));
cout << ret2.first->second << endl; //插入失败,得到的是原 key 为 30 的元素对应的 value:30 而不是新插入的 0
return 0;
}
insert 函数也可以插入 initializer_list 和构造函数那里一样:
hash2.insert({60,60})
erase 函数
erase 有三个重载的版本:
- 第一个版本:删除一个迭代器位置的元素。
- 第二个版本:删除键为 k 的元素。
- 第三个版本:删除一个迭代器区间。
#include<iostream>
#include<unordered_map>
using namespace std;
int main()
{
unordered_map<int, int> hash2({{10,10}, {20,20}, {30,30}}); //这是使用initializer_list来构造
hash2.erase(hash2.begin()); //第一个版本
hash2.erase(30); //第二个版本
hash2.erase(hash2.begin(), hash2.end()); //第三个版本
return 0;
}
void clear() const
清空 unordered_map
中所有的元素。
#include<iostream>
#include<unordered_map>
using namespace std;
int main()
{
unordered_map<int, int> hash2({{10,10}, {20,20}, {30,30}}); //这是使用initializer_list来构造
hash2.clear();
cout << hash2.size() << endl; // 输出:0
return 0;
}
unordered_set
这是 unordered_set
的介绍文档:来自 cpluscplus.com。
unordered_set 是一种不按特定顺序存储唯一元素的容器,可以根据元素的值快速检索单个元素。
在 unordered_set 中,元素的值同时也是其键,可以唯一地识别该元素。键是不可变的,因此,unordered_set 中的元素一旦进入容器就不能修改,但可以插入和移除。
在内部,unordered_set 中的元素不按任何特定顺序排序,而是根据它们的哈希值组织成桶,以便直接按其值快速访问单个元素(平均时间复杂度不变)。
无序集容器在按键访问单个元素时比集合容器更快,但在对元素子集进行范围迭代时,其效率通常较低。
容器中的迭代器至少是前向迭代器。
unordere_set 存储的数据只有一个 key。
unordered_set 与 unordered_map 的接口完全相同。这里就不再赘述了。