C++:map和set重点解析

目录

1.关联式容器

[2.set 容器](#2.set 容器)

3.map

[4. multiset 容器](#4. multiset 容器)


1.关联式容器

序列式容器:queue、vector、list,按照插入顺序存储数据,查找数据需要遍历时间复杂度为O(n)

今天说有序关联容器 map和set,是关联式容器的一种;map和set的底层是红黑树。而红黑树是基于搜索二叉树改进的。

关联式容器:数据之间有关联,之间符合一定的规则;便于查找。存储的不再是单一的元素,而是<key,value>的键值对,查找比较方便,时间复杂度为O(logN)量级。

关联式容器之间的规则依靠关键字(key)建立了逻辑关系,相比于序列式容器更加高效。

键值对 可以理解为一个结构有两个值 一个是key一个value,每个key和value一 一对应;C++中一般使用pair来表示键值对,

pair

cpp 复制代码
template <class T1, class T2> struct pair;

first 为 key second 为 value

2.set 容器

set - C++ 参考

上面的连接为set的介绍,

cpp 复制代码
template < class T,                        // set::key_type/value_type
           class Compare = less<T>,        // set::key_compare/value_compare
           class Alloc = allocator<T>      // set::allocator_type
           > class set;

注意

  1. set 存储的数据就是 key,按照 key 建立有序联系
  2. set 的 key 和 value 就是同一个模板参数,访问 set 的 value 就是访问 key 值。暂时理解为 set 中只存储一份 key (打个断点不确定)。
  3. set 不允许修改 key 值,因为会破坏以 key 值建立的逻辑关系;由于 value 和 key 是同一个值,因此 二着均不可修改。
  4. 不存储重复的值,底层为搜索二叉树,具有排序和去重的功能
  5. set 的 find 函数时间复杂度为 Olog(N),犹豫序列式容器的O(N)

3.map

map - C++ 参考

cpp 复制代码
template < class Key,                                     // map::key_type
           class T,                                       // map::mapped_type
           class Compare = less<Key>,                     // map::key_compare
           class Alloc = allocator<pair<const Key,T> >    // map::allocator_type
           > class map;

介绍

  1. map 是关联容器,根据关键值 key 进行排序存储键值和 value 组合成的元素
  2. 使用 pair 将 key 和 value 绑定在一起,然后存储。
  3. map 支持下标访问,可以通过 key 访问 value,下面我们详细说
  4. 底层为红黑树,和 set 一样,通过 key 值排序,然后存储pair。
  5. key 值是无法修改的,但是 value 是可以修改的

map的插入

cpp 复制代码
    map<string, string> mp;
	pair<string, string> kv = { "string","字符串" };
	mp.insert(kv);
	// C++11 多参数的构造函数隐式类型转换
	mp.insert({"insert","插入"});
	// C++98
	mp.insert(make_pair( "erase","消除"));
	// 强制类型转换
	mp.insert(pair<string, string>("sort", "排序"));

其他函数比较简单,这里说一下让 operator[ ]函数

operator[ ]的使用等价于 下面的结构

cpp 复制代码
(*((this->insert(make_pair(k,mapped_type()))).first)).second

下面的这段程序调用的是insert函数,

cpp 复制代码
(this->insert(make_pair(k,mapped_type()))

insert的返回值为 pair<iterator,bool>,相当于相面的程序

cpp 复制代码
(*(pair<iterator,bool>.first)).second
cpp 复制代码
(*(iterator).second

然后我们在看看迭代器

second 就是 value值,所以 [ ] 可以访问对应 key 的 value。并且具有插入的作用,看下述的程序

cpp 复制代码
void testmap3()
{
	map<string, string> dict;
	dict.insert(make_pair("string", "字符串"));
	dict.insert(make_pair("sort", "排序"));
	dict.insert(make_pair("insert", "插入"));
	dict["erase"];          //插入数据;
	dict["erase"] = "删除";  // 修改
	cout << dict["erase"] << endl; 
	dict["erase"] = "xxxxxx";  //修改
	dict["map"] = "映射、地图"; //插入+修改

	for (const auto& kv : dict)
	{
		cout << kv.first << ":" << kv.second << endl;
	}
}

4. multiset 容器

cpp 复制代码
template < class T,                        // multiset::key_type/value_type
           class Compare = less<T>,        // multiset::key_compare/value_compare
           class Alloc = allocator<T> >    // multiset::allocator_type
           > class multiset;

介绍 性质和set一样。但是不同的是可以存储多个相同key值。

测试如下,主要注意 count函数,返回相同 key 值出现的数量; equal_range函数,返回pair,一个等于值一个大于其的值,可以用于删除等于key的全部的值,lower_bound函数返回大于等于这个值得迭代器,upper_bound返回大于这个值得迭代器。

cpp 复制代码
void testset2()
{
	multiset<int> ms;
	int arr[] = { 1,2,88,8,7,3,5,9674,9,148,51,5,589,451,561,5,84,6,66,161,8 };

	for (const auto& e : arr)
	{
		ms.insert(e);
	}
	cout << ms.size() << endl;
	for (auto& e : ms)
	{
		cout << e << " ";
	}
	cout << endl;
	cout << "8:"<<ms.count(8) << endl;
	cout << "5:" << ms.count(5) << endl;
	auto ret = ms.equal_range(5);

	cout << *(ret.first) << endl;
	cout << *(ret.second) << endl;

	ms.erase(ret.first, ret.second);
	for (auto& e : ms)
	{
		cout << e << " ";
	}
	cout << endl;

}
相关推荐
CSDN_RTKLIB11 小时前
两版本锁抛出异常测试
c++
晨非辰11 小时前
Linux权限管理速成:umask掩码/file透视/粘滞位防护15分钟精通,掌握权限减法与安全协作模型
linux·运维·服务器·c++·人工智能·后端
IT陈图图12 小时前
构建 Flutter × OpenHarmony 跨端带文本输入对话框示例
开发语言·javascript·flutter
叫我辉哥e117 小时前
### 技术文章大纲:C语言造轮子大赛
c语言·开发语言
guygg8818 小时前
NOMA功率分配与64 QAM调制中的SIC的MATLAB仿真
开发语言·matlab
flushmeteor18 小时前
JDK源码-基础类-String
java·开发语言
u01092727119 小时前
C++中的策略模式变体
开发语言·c++·算法
雨季66620 小时前
构建 OpenHarmony 简易文字行数统计器:用字符串分割实现纯文本结构感知
开发语言·前端·javascript·flutter·ui·dart
雨季66620 小时前
Flutter 三端应用实战:OpenHarmony 简易倒序文本查看器开发指南
开发语言·javascript·flutter·ui
进击的小头20 小时前
行为型模式:策略模式的C语言实战指南
c语言·开发语言·策略模式