您现在的位置是:群英 > 开发技术 > 编程语言
C++中set怎么创建使用,有哪些特殊的用法
Admin发表于 2022-04-29 16:43:221634 次浏览
这篇文章给大家分享的是“C++中set怎么创建使用,有哪些特殊的用法”,文中的讲解内容简单清晰,对大家学习和理解有一定的参考价值和帮助,有这方面学习需要的朋友,接下来就跟随小编一起学习一下“C++中set怎么创建使用,有哪些特殊的用法”吧。


前言:

今天咱们继续来聊聊C++中的set。

上次的文章C++ set到底是什么遗留了一个问题没有回答,有些小伙伴有些疑问。就是为什么说set是关联式的容器,这个关联体现在哪里。

其实很简单,我们说过set的内部使用了红黑树对所有的元素进行了排序。在树结构当中,我们通常使用的都是<key, value>的形式。其中的key用来排序,value则是我们实际存储的值。只不过set有些特殊,它的valuekey是一样的,相当于是<key, key>的形式,所以它依然是关联式的容器。

今天这篇文章主要来聊聊setapi以及一些特殊的用法。

1、创建set

首先是set容器的类模板定义。

template < class T,     // 键 key 和值 value 的类型
           class Compare = less<T>,  // 指定 set 容器内部的排序规则
           class Alloc = allocator<T>  // 指定分配器对象的类型
           > class set;


其中第一个参数表示set当中元素的类型,第二个参数则是set容器内部的排序规则,第三个参数可以忽略,一般用不到。

set有3种构造函数,可以应用在不同的场景当中,我们简单来列举一下。

1.1 方法1

set<string> st;

最常规的一种,没有任何参数,直接创建。

1.2 方法2

set<string> st{"good", "bad", "medium"};


直接通过花括号枚举我们要传入set的值。

1.3 方法三

set<string> st{"good", "bad", "medium"};
set<string> st2(st);


拷贝创建,从另外一个set当中拷贝元素。

除了这三种形式的构造函数之外,还可以利用set类模板的第二个参数,传入元素排序规则来影响set中元素的排序,这勉强也算

是一种构造方法:

set<string, greater<string>> st{"good", "bad", "medium"};


我们不传入greater的排序结果是"bad", "good", "medium",当我们传入了这个参数之后,结果会变成:"medium", "good", "bad"。

这是因为我们传入的排序规则重新定义了元素的大小关系。

2、使用set

创建完了set就需要使用,使用无非增删改查。

我们先来说说增,往set里添加元素的函数有好几个,我们一个一个来说。

2.1 insert

insert函数非常简单,就直接调用,往set里插入即可。

st.insert("hhh");


但insert还可以批量插入多个元素:

st.insert({"hhh", "wow"});

2.2 emplace

emplace函数的功能和insert一样,可以往set当中插入元素。它和insert最大的区别在于emplace传入的参数并不是要插入的元素,而是构造元素需要的参数。

我这么说估计有点难理解,其实很简单,我们来对比一下就知道了。

假设我们有一个set它的类型是结构体P,当中我们重载了它的比较算子,这个先忽略。

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应该怎么操作呢?

P p{0, 3};
st.insert(p);


如果使用emplace函数呢,则是这样:

st.emplace(1, 23);


因为emplace的内部会替我们去调用结构体P的构造函数,使用1和23这两个参数构造出一个P的实例来存入set当中。

使用emplace可以节省掉创建实例的一步,所以通常工程当中往往大量使用emplace

emplace函数返回的结果是一个pairpair的第一个元素是set的迭代器,表示插入的元素的位置,第二个值是一个bool,表示是否插入成功。

2.3 emplace_hint

emplace函数的改进版,接受额外的参数表示插入set的位置。它的返回结果也有了一些变化,返回的是一个迭代器。

如果插入成功则返回新添加的元素,否则则指向set容器中和添加元素相同的元素。

使用emplace_hint会影响set中的有序性,一般不建议使用。

2.4 erase

说完了插入再说说删除,在set当中删除的方法只有一个就是erase,但是它却有好几种用法。

我们直接来看它的函数签名:

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

同样是查询函数,只不过它返回的不再是迭代器,而是一个整数,表示查询到元素的个数。

int cnt = st.count("good");

2.8 lower_bound 和 upper_bound

lower_boundupper_bound严格也算是查询函数,只不过它们查询的范围。lower_bound查询的是set当中第一个大于等于val的位置,而upper_bound查询的是set中第一个严格大于val的位置。

set<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的结果。

pair<set<string>::iterator, set<string>::iterator> ret = st.equal_range("i");

3、总结

到这里,关于set常用的方法基本上就都介绍完了,除此之外还有一些其他细枝末节的方法就不赘述了。比如像是size(),max_size()等等,大家有用到去查询即可。

但是有一个疑问不知道大家有没有发现,就是我们没有介绍到修改的函数。是set不支持修改吗?

关于这个问题的答案并不是老梁故意卖关子,而是它非常复杂,一句两句很难说清楚,老梁将在下一篇文章当中好好探讨一下这个问题。如果大家有修改元素的需求,可以用erase + insert代替。


关于“C++中set怎么创建使用,有哪些特殊的用法”的内容就介绍到这,感谢各位的阅读,相信大家对C++中set怎么创建使用,有哪些特殊的用法已经有了进一步的了解。大家如果还想学习更多知识,欢迎关注群英网络,小编将为大家输出更多高质量的实用文章!

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。

标签: c set用法
相关信息推荐
2022-10-11 09:25:45 
摘要:这篇文章主要为大家详细介绍了Spring中Bean的标签,文中的示例代码讲解详细,对我们学习Spring有一定的帮助,快跟随小编一起学习学习吧
2022-08-23 17:07:11 
摘要:给大家带来一篇关于jquery实现PC端轮播图代码分享的相关教程文章,内容涉及到jquery、轮播图、jquery写出PC端轮播图实例等相关内容
2022-02-08 20:09:59 
摘要:Java中怎样算三角形角度?对于求三角形角度我们在学习数学的时候会经常遇到,那么我们如何利用Java来解决三角形角度的问题呢?下面给大家分享一个示例,思路及实现方法如下,需要的朋友可以参考。
云活动
推荐内容
热门关键词
热门信息
群英网络助力开启安全的云计算之旅
立即注册,领取新人大礼包
  • 联系我们
  • 24小时售后:4006784567
  • 24小时TEL :0668-2555666
  • 售前咨询TEL:400-678-4567

  • 官方微信

    官方微信
Copyright  ©  QY  Network  Company  Ltd. All  Rights  Reserved. 2003-2019  群英网络  版权所有   茂名市群英网络有限公司
增值电信经营许可证 : B1.B2-20140078   粤ICP备09006778号
免费拨打  400-678-4567
免费拨打  400-678-4567 免费拨打 400-678-4567 或 0668-2555555
微信公众号
返回顶部
返回顶部 返回顶部