C++中的unordered_map常见用法详解
文章目录1. std::unordered_map 的定义与特性2. 构造 std::unordered_map3. 赋值操作4. 迭代器操作4.1 指向整个容器中的元素4.2 指向某个桶中的元素5. 容量操作6. 访问操作7. 插入操作8. 删除操作9. 查找操作10. 桶操作1. std::unordered_map 的定义与特性所在头文件:<unordered_map>std::
文章目录
- 1. std::unordered_map 的定义与特性
- 2. 构造 std::unordered_map
- 3. 赋值操作
- 4. 迭代器操作
- 5. 容量操作
- 6. 访问操作
- 7. 插入操作
- 8. 删除操作
- 9. 查找操作
- 10. 桶操作
1. std::unordered_map 的定义与特性
-
所在头文件:
<unordered_map>
-
std::unorederd_map
类模板:
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;
-
关联性:std::unorederd_map 是一个关联容器,其中的元素根据键来引用,而不是根据索引来引用。
-
无序性:在内部,std::unordered_map中的元素不会根据其键值或映射值按任何特定顺序排序,而是根据其哈希值组织到桶中,以允许通过键值直接快速访问各个元素(常量的平均时间复杂度)。
-
唯一性:std::unorederd_map中的元素的键是唯一的。
一些类型定义:
类型成员 | 定义 |
---|---|
key_type | 第一个模板参数(Key) |
mapped_type | 第二个模板参数(T) |
value_type | pair<const key_type,mapped_type> |
hasher | 第三个模板参数(Hash) |
key_equal | 第四个模板参数(Pred) |
2. 构造 std::unordered_map
构造方式 | 函数声明 |
---|---|
构造空的 unordered_map | 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 ); |
由一对范围迭代器指定输入 | 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() ); |
复制构造 | unordered_map ( const unordered_map& ump ); unordered_map ( const unordered_map& ump, const allocator_type& alloc ); |
移动构造 | unordered_map ( unordered_map&& ump ); unordered_map ( unordered_map&& ump, const allocator_type& alloc ); |
利用初始化列表构造 | unordered_map (initializer_list<value_type> il, size_type n = /* see below */, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& alloc = allocator_type() ); |
参数解释:
n : 初始时,桶的最小数量,即最少有多少个桶。
hf : 哈希函数对象。它是一个函数,根据传递给它的键计算并返回一个整数。
eql : 比较函数对象。如果传递给它的两个参数相等,则返回true.
例子:
// constructing unordered_maps
#include <iostream>
#include <string>
#include <unordered_map>
typedef std::unordered_map<std::string,std::string> stringmap;
stringmap merge (stringmap a,stringmap b) {
stringmap temp(a);
temp.insert(b.begin(),b.end());
return temp;
}
int main () {
stringmap first; // empty
// 一个元素为:{key, value}
stringmap second ( {{"apple","red"}, {"lemon","yellow"}} ); // init list
stringmap third ( {{"orange","orange"}, {"strawberry","red"}} ); // init list
stringmap fourth (second); // copy
stringmap fifth (merge(third,fourth)); // move
stringmap sixth (fifth.begin(),fifth.end()); // range
std::cout << "sixth contains:"<<endl;
for (auto& x: sixth)
std::cout << x.first << ":" << x.second<<endl;
std::cout << std::endl;
system("pause");
return 0;
}
运行结果:
3. 赋值操作
赋值方式 | 函数声明 |
---|---|
复制 | unordered_map& operator= ( const unordered_map& ump ); |
移动 | unordered_map& operator= ( unordered_map&& ump ); |
初始化列表 | unordered_map& operator= ( intitializer_list<value_type> il ); |
例子:
// assignment operator with unordered_map
#include <iostream>
#include <string>
#include <unordered_map>
typedef std::unordered_map<std::string, std::string> stringmap;
stringmap merge(stringmap a, stringmap b) {
stringmap temp(a);
temp.insert(b.begin(), b.end());
return temp;
}
int main() {
//stringmap first, second, third;//此处连续定义三个会报错。
stringmap first = { { "AAPL", "Apple" }, { "MSFT", "Microsoft" } }; // init list
stringmap second = { { "GOOG", "Google" }, { "ORCL", "Oracle" } }; // init list
stringmap third = merge(first, second); // move
first = third; // copy
std::cout << "first contains:"<<std::endl;
for (auto& elem : first)
std::cout << elem.first << ":" << elem.second<<std::endl;
std::cout << std::endl;
system("pause");
return 0;
}
运行结果:
4. 迭代器操作
4.1 指向整个容器中的元素
即,“第一个”指整个容器中的第一个,“尾后”指整个容器中的尾后。
函数声明 | 解释 |
---|---|
iterator begin() noexcept; const_iterator begin() const noexcept; | 返回一个迭代器,指向第一个元素 |
iterator end() noexcept; const_iterator end() const noexcept; | 返回一个迭代器,指向尾后元素 |
const_iterator cbegin() const noexcept; | 返回一个常量迭代器,指向第一个元素 |
const_iterator cend() const noexcept; | 返回一个常量迭代器,指向尾后元素 |
4.2 指向某个桶中的元素
即,“第一个”指某个桶中的第一个,“尾后”指某个桶中的尾后。
函数声明 | 解释 |
---|---|
local_iterator begin( size_type n ); const_local_iterator begin ( size_type n ) const; | 返回一个迭代器,指向第n个桶内的第一个元素 |
local_iterator end(size_type n); const_local_iterator end (size_type n) const; | 返回一个迭代器,指向第n个桶内的尾后元素 |
const_local_iterator cbegin( size_type n ) const; | 返回一个常量迭代器,指向第n个桶内的第一个元素 |
const_local_iterator cend( size_type n ) const; | 返回一个常量迭代器,指向第n个桶内的尾后元素 |
例子:
// unordered_map::cbegin/cend example
#include <iostream>
#include <string>
#include <unordered_map>
int main() {
std::unordered_map<std::string, std::string> mymap= { { "Australia", "Canberra" }, { "U.S.", "Washington" }, { "France", "Paris" } };
std::cout << "mymap contains:"<<std::endl;
for (auto it = mymap.cbegin(); it != mymap.cend(); ++it)
std::cout << it->first << ":" << it->second<<std::endl; // cannot modify *it
std::cout << std::endl;
std::cout << "mymap's buckets contain:\n";
for (unsigned i = 0; i < mymap.bucket_count(); ++i) {
std::cout << "bucket #" << i << " contains:";
for (auto local_it = mymap.cbegin(i); local_it != mymap.cend(i); ++local_it)
std::cout << local_it->first << ":" << local_it->second;
std::cout << std::endl;
}
system("pause");
return 0;
}
运行结果:
5. 容量操作
函数声明 | 解释 |
---|---|
bool empty() const noexcept; | unordered_map 是否为空 |
size_type size() const noexcept; | 获取unordered_map 中元素的数量 |
6. 访问操作
访问方式 | 函数声明 | 解释 |
---|---|---|
使用方括号([]) | mapped_type& operator[] (const key_type& k); mapped_type& operator[] (key_type&& k); | 如果 k 匹配容器中某个元素的键,则该函数返回该映射值的引用。 如果 k 与容器中任何元素的键都不匹配,则该函数将使用该键插入一个新元素,并返回该映射值的引用。 |
使用 at() | mapped_type& at (const key_type& k); const mapped_type& at (const key_type& k) const; | 如果 k 匹配容器中某个元素的键,则该函数返回该映射值的引用。 如果 k 与容器中任何元素的键都不匹配,则该函数将抛出 out_of_range 异常。 |
注意:const std::unordered_map 不能使用 operator[] 操作!!
例子:
// unordered_map::at
#include <iostream>
#include <string>
#include <unordered_map>
int main() {
std::unordered_map<std::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) {
std::cout << x.first << ": " << x.second << std::endl;
}
system("pause");
return 0;
}
运行结果:
7. 插入操作
插入方式 | 函数声明 | 说明 |
---|---|---|
插入单个元素 | pair<iterator,bool> insert (const value_type& val); template <class P> pair<iterator,bool> insert (P&& val); // 类型P应当可以转换为 value_type类型 | 返回一个pair,其中第一个值为一个迭代器,指向新插入的元素或其键等于待插入元素的键的元素(原先就已存在的元素);第二个值是一个bool值,当插入一个新元素时,该值设为true,当该键已存在时,该值设为false |
带插入位置提示 | iterator insert (const_iterator position, const value_type& val); template <class P> iterator insert (const_iterator position, P&& val); | 返回一个迭代器,该迭代器指向新插入的元素或指向键相等的已存在元素。 |
由一对范围迭代器指定输入 | template <class InputIterator> void insert (InputIterator first, InputIterator last); | |
使用初始化列表指定插入元素 | void insert (initializer_list<value_type> il); |
例子:
// unordered_map::insert
#include <iostream>
#include <string>
#include <unordered_map>
int main() {
std::unordered_map<std::string, double>
myrecipe,
mypantry = { { "milk", 2.0 }, { "flour", 1.5 } };
std::pair<std::string, double> myshopping("baking powder", 0.3);
myrecipe.insert(myshopping); // copy insertion
myrecipe.insert(std::make_pair<std::string, double>("eggs", 6.0)); // move insertion
myrecipe.insert(mypantry.begin(), mypantry.end()); // range insertion
myrecipe.insert({ { "sugar", 0.8 }, { "salt", 0.1 } }); // initializer list insertion
std::cout << "myrecipe contains:" << std::endl;
for (auto& x : myrecipe)
std::cout << x.first << ": " << x.second << std::endl;
std::cout << std::endl;
system("pause");
return 0;
}
运行结果:
8. 删除操作
删除方式 | 函数声明 | 说明 |
---|---|---|
根据元素位置 | iterator erase (const_iterator position); | 返回一个迭代器,指向被删除元素的后一个元素 |
根据元素的键 | size_type erase (const key_type& k); | 返回被删除元素的数目,此处为1 |
由一对范围迭代器指定删除的范围 | iterator erase (const_iterator first, const_iterator last); | 返回一个迭代器,指向最后一个被删除元素的后一个元素 |
删除所有元素 | void clear() noexcept; |
例子:
// unordered_map::erase
#include <iostream>
#include <string>
#include <unordered_map>
int main() {
std::unordered_map<std::string, std::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";
// erase examples:
mymap.erase(mymap.begin()); // erasing by iterator
mymap.erase("France"); // erasing by key
mymap.erase(mymap.find("China"), mymap.end()); // erasing by range
// show content:
for (auto& x : mymap)
std::cout << x.first << ": " << x.second << std::endl;
system("pause");
return 0;
}
运行结果:
9. 查找操作
函数声明 | 说明 |
---|---|
iterator find (const key_type& k); const_iterator find (const key_type& k) const; | 在容器中搜索键值等于 k 的元素,如果找到,则返回一个指向该元素的迭代器,否则返回一个指向unordered_map :: end的迭代器。 |
例子:
// unordered_map::find
#include <iostream>
#include <string>
#include <unordered_map>
int main () {
std::unordered_map<std::string,double> mymap = {
{"mom",5.4},
{"dad",6.1},
{"bro",5.9} };
std::string input;
std::cout << "who? ";
getline (std::cin,input);
// 查找
std::unordered_map<std::string,double>::const_iterator got = mymap.find (input);
if ( got == mymap.end() )
std::cout << "not found";
else
std::cout << got->first << " is " << got->second;
std::cout << std::endl;
system("pause");
return 0;
}
运行结果:
10. 桶操作
函数声明 | 说明 |
---|---|
size_type bucket_count() const noexcept; | 获取容器中桶的数目 |
size_type bucket_size ( size_type n ) const; | 获取第 n 个桶中元素的数量 |
size_type bucket ( const key_type& k ) const; | 获取键为 k 的元素所在桶的序号 |
参考:http://www.cplusplus.com/reference/unordered_map/unordered_map/
以上博文来自:
更多推荐
所有评论(0)