set基本介绍
set是key模型,本质是确定一个
元素在不在此容器中,也就是说
set中存储的是一个单一数据
1. set是按照一定次序存储元素的容器
2. 在set中,元素的value也标识它(value就是key,类型为T),并且每个value必须是唯一的。set中的元素不能在容器中修改(元素总是const),
但是可以从容器中插入或删除它们。
3. 在内部,set中的元素总是按照其内部比较对象(类型比较)所指示的特定严格弱排序准则进行排序。
4. set容器通过key访问单个元素的速度通常比unordered_set容器慢,但它们允许根据顺序对子集进行直接迭代。
5. set在底层是用二叉搜索树(红黑树)实现的。
set的模板参数只有T
set只支持增删查,不支持改!
set结构中遍历出来是
数据有序并且去重的!
map基本介绍
map和set的区别就是,map中存储
的并不是一个单一数据,而是存储了
一个pair结构!(后面会讲解)
1. map是关联容器,它按照特定的次序(按照key来比较)
存储由键值key和值value组合而成的元素。
2. 在map中,键值key通常用于排序和惟一地标识元素,而值value中存储与此键值key关联的内容。键值key和值value的类型可能不同,
并且在map的内部,key与value通过成员类型value_type绑定在一起,
为其取别名称为pair:
typedef pair<const key, T> value_type;
3. 在内部,map中的元素总是按照键值key进行比较排序的。
4. map中通过键值访问单个元素的速度通常比unordered_map容器慢,但map允许根据顺序对元素进行直接迭代(即对map中的元素进行迭代时,
可以得到一个有序的序列)。
5. map支持下标访问符,即在[]中放入key,就可以找到与key对应的value。
6. map通常被实现为二叉搜索树(更准确的说:平衡二叉搜索树(红黑树))。
map的模板参数中有key和T
map都支持增删查,不支持改!
map结构中遍历出来是
数据有序并且去重的!
pair结构介绍
pair结构实际上是一个键值对:
template <class T1, class T2>
struct pair
{
T1 first;
T2 second;
pair(): first(T1()), second(T2())
{}
pair(const T1& a, const T2& b): first(a), second(b)
{}
};
它实际上就是封装了两个可以是不同
类型的数,它可以用作中英字典,存储
pair<string,string>的结构,first存储中文
second存储对应的英文解释。
map中存储的就是pair结构,所以
map也叫存储的KV模型,因为first和
second对应key和value
map的三种常见使用方法:
1. 方法一: 定义pair对象后插入
map<string,string> dict;
pair<string,string> kv1("排序","sort");
pair<string,string> kv2("左边","left");
dict.insert(kv1);
dict.insert(kv2);
2. 方法二: 使用匿名对象插入
map<string,string> dict;
dict.insert(pair<string,string>("排序","sort"));
dict.insert(pair<string,string>("左边","left"));
3. 方法三: 使用make_pair插入
map<string,string> dict;
dict.insert(make_pair("排序","sort"));
dict.insert(make_pair("左边","left"));
显而易见,make_pair是最方便的也是最常用的方法!
set详解
可以看到,第二个模板的第二个参数是less,
set默认情况下遍历出是升序,
但是定义对象显示传参greater就会变为降序!
set<int,greater<int>> s;
插入函数insert
插入我们需要关心三点:
一是插入可以不用写pos,直接插入
二是可以插入一段迭代器区间
三是插入的返回值也是一个pair结构
pair中存储了布尔类型和迭代器,分别
代表此次插入是否成功,若成功则返回
被插入元素迭代器的位置
查找函数find
删除函数erase
map详解
相较于set,map还
支持方括号的使用:
map的方括号设计的十分巧妙
它的参数的pair中的first,返回值
是pair中的second,并且它返回的是
引用,可以根据first修改second
它可以用来计数:
string arr[]={"苹果","西瓜","香蕉","苹果","西瓜","西瓜","西瓜","苹果"};
map<string,int> countmap;
for(auto str : arr)
{
countmap[str]++;
}
方括号自带插入功能,当
出现第一个"苹果"时,会自动把"苹果"
插入到map中,第二次遇见"苹果"时,
会将"苹果"的计数++变成2
删除函数
查找函数
erase和find传参只用传pair中的first
类型的参数,即可完成任务,并且find的
返回值和set的find是一样的
multimap和multiset
map和set的遍历是有序并且去重的
也就是说里面没有相同的元素,但是
STL提供了multimap和multiset
它们允许存在相同的元素!
multimap不支持方括号!
当我们插入相同的数据时,它也会保存
总结
熟悉map和set的使用在平常做题
时会有大用处,但是平时用的更多的
是unordered_map/set,不过它们的
使用方法基本一致。