C++中set 的⽤法
⽬录
1、创建set
1.1 ⽅法1
1.2 ⽅法2
1.3 ⽅法三
2、使⽤set 2.1 insert 2.2 emplace 2.3 emplace_hint 2.4 erase 2.5 clear 2.6 find 2.7 count
2.8 lower_bound 和 upper_bound 2.9 equal_range
3、总结
今天咱们继续来聊聊C++中的set 。
上次的⽂章遗留了⼀个问题没有回答,有些⼩伙伴有些疑问。就是为什么说set 是关联式的容器,这个关
联体现在哪⾥。其实很简单,我们说过set 的内部使⽤了红⿊树对所有的元素进⾏了排序。在树结构当中,我们通常使⽤的都是<key, value>的形式。其中的key ⽤来排序,value 则是我们实际存储的值。只不过set 有些特殊,它的value 和key 是⼀样的,相当于是<key, key>的形式,所以它依然是关联式的容器。
今天这篇⽂章主要来聊聊set 的api 以及⼀些特殊的⽤法。
1、创建set
123
template < class T, // 键 key 和值 value 的类型
class Compare = less<T>, // 指定 set 容器内部的排序规则
class Alloc = allocator<T> // 指定分配器对象的类型
其中第⼀个参数表⽰set
当中元素的类型,第⼆个参数则是set 容器内部的排序规则,第三个参数可以忽略,⼀般⽤不到。set 有3种构造函数,可以应⽤在不同的场景当中,我们简单来列举⼀下。
1.1 ⽅法1
set<string> st;
最常规的⼀种,没有任何参数,直接创建。
1.2 ⽅法2
set<string> st{"good", "bad", "medium"};
直接通过花括号枚举我们要传⼊set 的值。
1.3 ⽅法三
1
set<string> st{"good", "bad", "medium"};
set<string> st2(st);
拷贝创建,从另外⼀个set 当中拷贝元素。
除了这三种形式的构造函数之外,还可以利⽤set 类模板的第⼆个参数,传⼊元素排序规则来影响set 中元素的排序,这勉强也
算
我们不传⼊greater 的排序结果是"bad ", "good ", "medium ",当我们传⼊了这个参数之后,结果会变成:"medium ", "good ", "bad "。这是因为我们传⼊的排序规则重新定义了元素的⼤⼩关系。
2、使⽤set
创建完了set 就需要使⽤,使⽤⽆⾮增删改查。
我们先来说说增,往set ⾥添加元素的函数有好⼏个,我们⼀个⼀个来说。
2.1 insert
insert 函数⾮常简单,就直接调⽤,往set
⾥插⼊即可。
st.insert("hhh");
st.insert({"hhh", "wow"});
2.2 emplace
emplace 函数的功能和insert ⼀样,可以往set 当中插⼊元素。它和insert 最⼤的区别在于emplace 传
⼊的参数并不是要插⼊的元素,⽽是构造元素需要的参数。
我这么说估计有点难理解,其实很简单,我们来对⽐⼀下就知道了。
假设我们有⼀个set 它的类型是结构体P ,当中我们重载了它的⽐较算⼦,这个先忽略。
12345678
struct P { int x, y; P(int x, int y) : x(x), y(y){}; bool operator<(const P b) const { return this->x < b.x; }};
set<P> st;
如果我们要使⽤insert 应该怎么操作呢?
1
P p{0, 3};
st.insert(p);
因为emplace 的内部会替我们去调⽤结构体P 的构造函数,使⽤1和23这两个参数构造出⼀个P 的实例来存⼊set 当中。使⽤emplace 可以节省掉创建实例的⼀步,所以通常⼯程当中往往⼤量使⽤emplace 。
emplace 函数返回的结果是⼀个pair ,pair 的第⼀个元素是set 的迭代器,表⽰插⼊的元素的位置,第⼆个值是⼀个bool ,表⽰是否插⼊成功。
2.3 emplace_hint
emplace 函数的改进版,接受额外的参数表⽰插⼊set 的位置。它的返回结果也有了⼀些变化,返回的是⼀个迭代器。如果插⼊成功则返回新添加的元素,否则则指向set 容器中和添加元素相同的元素。
c++中string的用法使⽤emplace_hint 会影响set 中的有序性,⼀般不建议使⽤。
2.4 erase
说完了插⼊再说说删除,在set 当中删除的⽅法只有⼀个就是erase ,但是它却有好⼏种⽤法。
12
size_type erase (const value_type& val);iterator erase (const_iterator position);
iterator erase (const_iterator first, const_iterator last);
第⼀种⽅法我们传⼊了⼀个val 值,也就是我们要删除的元素。
第⼆种⽅法我们传⼊的是⼀个迭代器,它会删除迭代器指向的元素。第三种⽅法类似,只不过我们传⼊的是两个迭代器,表⽰⼀个范围,它会删除这个范围内所有的元素。
第⼀种⽅法的返回值是⼀个整数,表⽰删除的元素个数。后⾯两种返回的都是⼀个迭代器,指向删除元素后⾯⼀个位置。
2.5 clear
清空set 。
2.6 find
set 中的查询函数,传⼊我们要查询的value ,返回⼀个迭代器。
set<string>::iterator it = st.find("good");
如果成功到则返回指向该元素的迭代器,否则指向end 。
2.7 count
同样是查询函数,只不过它返回的不再是迭代器,⽽是⼀个整数,表⽰查询到元素的个数。
2.8 lower_bound 和 upper_bound
lower_bound和upper_bound严格也算是查询函数,只不过它们查询的范围。lower_bound查询的是set当中第⼀个⼤于等于val的位置,⽽upper_bound查询的是set中第⼀个严格⼤于val的位置。
1set<string>::iterator it_low = st.lower_bound("i");
set<string>::iterator it_up = st.upper_bound("i");
同样这两个函数返回的是⼀个迭代器。
2.9 equal_range
这个函数返回的是⼀个pair,它的第⼀个元素是lower_bound的结果,第⼆个元素是upper_bound的结果。
3、总结
到这⾥,关于set常⽤的⽅法基本上就都介绍完了,除此之外还有⼀些其他细枝末节的⽅法就不赘述了。⽐如像是
size(),max_size()等等,⼤家有⽤到去查询即可。
但是有⼀个疑问不知道⼤家有没有发现,就是我们没有介绍到修改的函数。是set不⽀持修改吗?
关于这个问题的答案并不是⽼梁故意卖关⼦,⽽是它⾮常复杂,⼀句两句很难说清楚,⽼梁将在下⼀篇⽂章当中好好探讨⼀下这个问题。如果⼤家有修改元素的需求,可以⽤erase + insert代替。
到此这篇关于C++中 set的⽤法的⽂章就介绍到这了,更多相关C++ set⽤法内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论