文章目录

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_typepair<const key_type,mapped_type>
hasher第三个模板参数(Hash)
key_equal第四个模板参数(Pred)

2. 构造 std::unordered_map

构造方式函数声明
构造空的 unordered_mapexplicit 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/


以上博文来自:

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐