C++ 11中unordered_set和unordered_map简单介绍和运用

本文介绍了C++ STL中的unordered_set和unordered_map容器,它们利用哈希数据结构实现了常数时间的插入、查找和移除,适用于存放散列数据。unordered_set用于存储唯一元素,而unordered_map则以键值对形式存储,提供了丰富的成员函数和接口。

C++STL中的hash数据结构
——unordered_set

参考链接
leetcode题目推荐
用于存放hash散列,其搜索插入移除通常为常数时间,其原理是声明一个有n个桶的数据结构
特点:

  • unordered_set为一种容器,以不特定的顺序存储唯一元素,可根据值检索
  • unordered_set中,元素的值同时事唯一标识它的键,键不可变,只可以增删。
  • 在内部,unordered_set中的元素没有按照任何特定的顺序排序,而是根据它们的散列值组织成桶(一个线性链表代表一个桶),从而允许通过它们的值直接快速访问单个元素(平均时间复杂度为常数)[想象一下拉链法]
  • unordered_set容器比set容器更快地通过它们的键访问单个元素,尽管它们在元素子集的范围迭代中通常效率较低;容器中的迭代器只能是正向迭代器

基本的函数

构造

std::unordered_set<std::string> c:           //初始化容器;

//初始化容器,并将"aaa", "bbb", "ccc"加入到容器中;
std::unordered_set<std::string> c{ "aaa", "bbb", "ccc" }:  

std::unordered_set<std::string> c{ 16 }:    //初始化容器,并设置16个桶;

添加

c.insert("dddd"):                      //向容器添加元素”dddd";
a.insert({ "aaa","bbbb","cccc" }):     //向容器添加元素"aaa","bbbb","cccc";

//b是一个存储着和a相同类型元素的向量,可将b中所有元素添加到a中。
a.insert(b.begin(), b.end()):      

查找

a.find("eeee"):查找元素"eeee",返回结果为a.end()则表明没有找到,否则返回所对应元素;

a.count("eeee"):查找元素"eeee"在a中有几个(由于unordered_set中没有相同的元素,所以结果通常为0或1)。   

查找桶接口

a.bucket_count():返回数据结构中桶的数量;

a.bucket_size(i):返回桶i中的大小;

a.bucket(“eeee"):返回元素"eeee"在哪个桶里。

观察器

a.hash_function()("aaa"):返回"aaa"所对应的hash值;

a.key_eq()("aaa","aaaa") :当元素相同时返回true,否则返回false。

清除元素

a.clear():清除a中所有元素;

a.erase("aaa"):清除元素"aaa"。

统计函数

a.size():返回a中总的元素个数;

a.max_size():返回a中最大容纳元素;

a.empty():判断a中是否为空。

C++STL中的hash容器
——unordered_map

参考链接1
参考链接2
参考链接3——B站一个简单的使用视频
leetcode题目推荐——桶排序相关练习
C++ 11中加入unordered系列容器,unorderd_map用法与上述set用法基本类似;在运用中常与map结构进行对比

  • 查找插入效率:
    • unordered_map > hash_map > map
  • 空间复杂度:
    • map > unordered_map > hash_map
  • unorder_map容器中的数据是无序的,而map中的是有序的,因其采用红黑树实现,故进行中序遍历会得到有序遍历。

特性和使用

  • 采用键值对(pair类型)的形式存储数据,各个键值对的键互不相同且不允许修改,容器内部不会对键值对进行排序
  • 使用时应加入 #include <unordered_map>
  • unordered_map的迭代器是一个指针,指向这个元素,通过迭代器取得其值,键值分别是迭代器的first和second属性,如:

unordered_map<Key, T>::interator it;
it->first;
it->second;

成员函数

迭代器

begin    返回指向容器起始位置的迭代器(iterator)   
end      返回指向容器末尾位置的迭代器   
cbegin   返回指向容器起始位置的常迭代器(const_iterator)   
cend     返回指向容器末尾位置的常迭代器 

Capacity

size        返回有效元素个数 
max_size    返回 unordered_map 支持的最大元素个数 
empty       判断是否为空 

元素访问

operator[]     访问元素 
at         访问元素 

元素修改

insert    插入元素 
erase   删除元素 
swap    交换内容 
clear     清空内容 
emplace  构造及插入一个元素 
emplace_hint 按提示构造及插入一个元素

操作

find       通过给定主键查找元素,没找到:返回unordered_map::end
count      返回匹配给定主键的元素的个数 
equal_range   返回值匹配给定搜索值的元素组成的范围 

Buckets

bucket_count    返回槽(Bucket)数 
max_bucket_count    返回最大槽数 
bucket_size       返回槽大小 
bucket       返回元素所在槽的序号 
load_factor     返回载入因子,即一个元素槽(Bucket)的最大元素数 
max_load_factor    返回或设置最大载入因子 
rehash       设置槽数 
reserve        请求改变容器容量
C++中,unordered_set unordered_map 都是基于哈希表实现的无序关联容器,它们之间的主要区别在于存储的数据类型使用的场景,具体区别如下: 1. **键值对 vs. 单一值**:unordered_set 存储单一值,每个元素独一无二;而 unordered_map 存储键值对,键具有唯一性,通过键来访问对应的值。例如,若要存储一系列不重复的整数,可使用 unordered_set;若要存储学生姓名对应成绩,就需要 unordered_map,其中姓名为键,成绩为值 [^1]。 2. **查找方式**:由于存储结构不同,查找方式也有差异。unordered_set 直接查找元素是否存在;unordered_map 则通过键查找对应的值。示例代码如下: ```cpp #include <iostream> #include <unordered_set> #include <unordered_map> int main() { // unordered_set示例 std::unordered_set<int> mySet = {1, 2, 3, 4, 5}; auto setIt = mySet.find(3); if (setIt != mySet.end()) { std::cout << "unordered_set中找到了元素3" << std::endl; } // unordered_map示例 std::unordered_map<std::string, int> myMap = {{"apple", 1}, {"banana", 2}, {"cherry", 3}}; auto mapIt = myMap.find("banana"); if (mapIt != myMap.end()) { std::cout << "unordered_map中找到了键banana,对应的值是: " << mapIt->second << std::endl; } return 0; } ``` 3. **使用场景**:当只需要判断元素是否存在,不需要关联其他信息时,unordered_set 是更好的选择;而当需要存储元素并且要关联额外信息时,unordered_map 更合适。例如,在处理单词去重时,用 unordered_set 存储单词;在统计单词出现次数时,用 unordered_map,键为单词,值为出现次数 [^1]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值