关联容器专题

基本用法

  • 有序头文件:
#include<set>  //set和multiset的头文件
#include<map> //map和multimap的头文件
  • 头文件:
#include<unordered_set>  
//unordered_set和unordered_multiset的头文件
#include<unordered_map>
 //unordered_map和unordered_multimap的头文件
  1. unordered_xxx的用法和xxx的用法基本相同
  2. multi_xxxxxx的用法基本相同

set基本用法

  • 声明:
set<int> A;   //元素类型为string对象
set<int, less<int> > A;   //按递减方式排序
  • 初始化:
string s1[N] = {"buffoon", "thinkers", "for", "heavy", "can", "for"};
set<string> A(s1, s1+N);
  1. A中的元素是惟一的且已经进行了排序
  • 交、并、补
set_union(A.begin(), A.end(), B.begin(), B.end(), insert_iterator<set<string> >(C, C.begin()));
//前两个迭代器定义了第一个集合的区间,接下来的两个定义了第二个集合区间,最后一个迭代器是输出迭代器
//set_intersection()用于求两个集合的交集,接口和set_union()相同
//set_difference()用于获得两个集合的差,接口和set_union()相同
  • 查找指定范围元素
  1. low_bound() 将键作为参数并返回一个迭代器,该迭代器指向集合中第一个不小于键参数的成员。
  2. upper_bound()将键作为参数并返回一个迭代器,该迭代器指向集合中第一个不大于键参数的成员。
  • 插入&删除:
string s("tennis");
A.insert(s);                //插入一个值
B.insert(A.begin(), A.end()); //插入一个范围
A.erase(s);   //删除一个值
  • 判断是否存在:
A.count('a');  //返回1表示存在,返回0表示不存在
A.find('a') == A.end();  //相等表示不存在,不相等表示存在
vector<int> nums{ 1, -1, -1};
unordered_multiset<int> m_multiset{ nums.begin(), nums.end() };
for (int i = 0; i < nums.size(); i++)
{
	cout << "find key" << nums[i] << endl;
	for (auto iter = m_multiset.find(nums[i]); iter != m_multiset.end(); iter++)
	{
		cout << *iter << endl;
	}
}

在这里插入图片描述

  1. find只能告知该键是否存在,以及该键值所在的位置
  2. 如果存在多个key相同的key-value,不能使用find返回的迭代器直接遍历到end(),它只是告知你该keyhash表底层数据结构中的位置,并不保证从该位置到end()之间的key都是你要找的key
vector<int> nums{ 1, -1, -1 };
unordered_multiset<int> m_multiset{ nums.begin(), nums.end() };
for (int i = 0; i < nums.size(); i++)
{
	cout << "find key" << nums[i] << endl;
	for (auto iter = m_multiset.find(nums[i]); iter != m_multiset.end() && *iter == nums[i]; iter++)
	{
		cout << *iter << endl;
	}
}

在这里插入图片描述

pair基本用法

  1. pair类型不是关联容器,而是一个键-值对,一般用于key-value的关联容器
pair<int, char> item1 {1, 'a'};  //创建pair
make_pair(1, 'a'); //标准函数也会产生一个pair<int, char>类型的对象
//访问:
cout<<item1.first<<endl; //获取键(第一个值)
cout<<item1.second<<endl;//获取值(第二个值)

map基本用法

map<int, char> my_map;
//插入/修改:
my_map[1] = 'a';

pair<int, char> item(2, 'b');
my_map.insert(item);

my_map.insert(pair<int, char> (3, 'c')); //利用匿名pair<int, char>对象
my_map.insert(make_pair(4, 'd'));  //利用make_pair函数
my_map.insert({5, 'e'});  //直接使用大括号
  • map的初始化:
  1. multimapmap初始化方式相同,但key重复不会被覆盖
map<int, char> m_map{{1, 'a'},{2, 'b'},{3, 'c'},{3, 'd'}};
multimap<int, char> m_multiset {{1, 'a'},{2, 'b'},{3, 'c'},{3, 'd'}};

在这里插入图片描述

  • 判断某个键值是否被插入:
my_map.count(2); //判断key=2的键值对是否被插入,若返回1则已插入,返回0则未插入
auto iter = my_map.find(2);  //判断key=2的键值对是否被插入
if(iter != my_map.end())  //若iter != my_map.end()则已被插入,否则未被插入
  • map的遍历:
for(auto iter = my_map.begin(); iter != my_map.end(); iter++)
{
	cout << iter->first << " "<<iter->second<<endl;
}

multi_xxx和xxx的区别

  • multimap vs map
  1. multimap的用法与map的用法基本相同,但multimap可以插入多个相同而不同的键值对
multimap<int, char> my_multimap;
my_multimap.insert({ 5, 'a' });
my_multimap.insert({ 5, 'b' });
my_multimap.insert({ 5, 'c' });
auto range_pair = my_multimap.equal_range(5);
for (auto iter = range_pair.first; iter != range_pair.second; iter++)
{
	cout << iter->first << " " << iter->second << endl;
}

unordered_xxx和xxx的区别

  • unordered_set/unordered_multiset vsset/multiset
  1. 无序关联容器unordered_set/multiset,由于底层使用hash table因此会增加一些hash_table相关的接口,但基本不会被使用
  2. set/multiset会按键的大小进行排序,而unordered_set/unordered_mutiset不会进行排序
  3. set/multiset提供了rbeginrend方法,而unordered_setunordered_mutiset未提供
multiset<int> m_multiset{ 5, 3, 4, 4, 1, 2 };
unordered_multiset<int> m_Umultiset{ 5, 3, 4, 4, 1, 2 };
for (int key : m_multiset)
	cout << key << " ";
cout << endl;
for (int key : m_Umultiset)
	cout << key << " ";
cout << endl;

在这里插入图片描述

基本原理

有序关联容器

  1. 定义:关联在一起,并使用来查找值
  2. 优点: 提供了对元素的快速访问
  3. 关联容器允许插入新元素,但无法指定插入位置
  4. 种类setmultisetmapmultimap
  5. 有序关联容器对容器内的元素按key进行排序
  6. 有序关联容器底层是基于红黑树结构实现的
key-val组合key
key不可重复mapset
key可重复multimapmultiset

无序关联容器

  1. 定义:关联在一起,并使用来查找值
  2. 种类:unordered_setunordered_multisetunordered_mapunordered_multimap
  3. 无序关联容器不对容器内的元素进行排序
  4. 无序关联容器底层是基于哈希表实现的
key-val组合key
key不可重复unordered_mapunordered_set
key可重复unordered_multimapunordered_multiset

相关问题

  • unordered_map和map的区别和应用场景的区别:
  1. map支持自动排序,底层为红黑树,因此插入和查询的时间复杂度为 O ( l o g n ) O(log^n) O(logn),而unordered_map底层为哈希表,查询的时间复杂度为 O ( 1 ) O(1) O(1)
  2. 红黑树需要维护父节点子节点以及颜色信息,因此占用空间更高,而哈希表维护时间与bucket桶维护的链表长度有关
  3. map适用于有序数据的应用场景,而unordered_map适用于高效查询的应用场景
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

m0_46427273

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值