1. 基本概念
unordered_set是无序数据集,也就是没有以特别的顺序存储数据。这个是基于哈希表实现的数据容器。哈希表本质上是一个数组,与常见的数组不同的是,哈希表中存放的值是键值对。键值对就是可以根据一个键值获取对应的一个值。而对于键值,百度百科的解释是“键值(key)是windows中注册表中的概念。键值位于注册表结构链末端,和文件系统的文件类似,包含当前计算机及应用程序执行时使用的实际配置信息和数据。键值包含几种数据类型,以适应不同环境的使用需求。”通过一个键值获取对应的一个值,这个有点类似高等数学中的映射。一个简单的例子在这里说明这个概念。
假设:有一本中文词典,里面包含了所有的汉字,但是这些汉字是按任意顺序随意排版的,那么想要在其中找到某一个汉字,你就需要从头至尾一个一个核查,如果运气差,这个汉字正好在词典的末尾,那你需要遍历整本词典才能找到你要查的汉字。
优化:因为汉字和拼音之间存在着一种确定的关系,为了提高查找速度,现在将所有汉字按照拼音(key)进行排序(拼音可以根据首字母,第二个字母依次进一步排序),并且每个拼音都有一个对应页码(index),从该页开始,存放拼音对应的汉字(value)。所以找到拼音,也就能在对应的页码找到对应的汉字。其中,拼音和页码之间,有着某种固定的映射关系,可以通过某种方式计算出来(hash function)。
从上面的例子可以看出这个容器在数据查找、容器遍历方面具有相当优势,所以对于查找问题可以考虑使用该容器。另外,这个容器存储的数据是唯一的,这个特性可以用于快速检查某段数据序列是否存在重复值。
2. 用法
- 定义和初始化
// constructing unordered_sets
#include <iostream>
#include <string>
#include <unordered_set>
template<class T>
T cmerge (T a, T b) {
T t(a); t.insert(b.begin(),b.end()); return t; }
int main ()
{
std::unordered_set<std::string> first; // empty
std::unordered_set<std::string> second ( {
"red","green","blue"} ); // init list
std::unordered_set<std::string> third ( {
"orange","pink","yellow"} ); // init list
std::unordered_set<std::string> fourth ( second ); // copy
std::unordered_set<std::string> fifth ( cmerge(third,fourth) ); // move
std::unordered_set<std::string> sixth ( fifth.begin(), fifth.end() ); // range
std::cout << "sixth contains:";
for (const std::string& x: sixth) std::cout << " " << x;
std::cout << std::endl;
return 0;
输出:
sixth contains: pink yellow red green orange blue
- 成员方法
(1)begin():返回指向第一元素的迭代器(迭代器(iterable)是一个超级接口! 是可以遍历集合的对象,为各种容器提供了公共的操作接口,隔离对容器的遍历操作和底层实现,从而解耦)。
原型:
<1> container iterator (1)
iterator begin() noexcept;
const_iterator begin() const noexcept;
<2> bucket iterator (2)
local_iterator begin ( size_type n );
const_local_iterator begin ( size_type n ) const;
根据函数原型,可以知道begin可以返回两种迭代器类型,其中iterator可以改变所指向元素的值,而const_iterator不可改,只可更改其指向其他元素。也就是const_iterator可以修改自身的指向,但不可以修改所指向的位置的值。
(2)end():返回指向最后一个元素的迭代器。
原型:
<1> container iterator