C++ STL中的set详解
创始人
2024-01-26 00:16:54

前言

在学习csp题解的时候接触到这个数据结构,故在此记录一下其概念及应用。

基本概念

set的底层采用的是红黑树,所有元素都会根据元素的键值自动排序,方便管理元素,但不支持直接修改键值。

应用

头文件调用

#include 
#include 

set的Api

insert  插入元素

@brief  试图将元素插入到%set中。

@param[in]  要插入的元素。

@return  ::iterator, bool>  <迭代器,插入是否成功标志>

erase  擦除元素

@brief  根据提供的键擦除元素。

@param[in]  要擦除的元素的键。

@return  std::size_t  被擦除的元素的数量。此函数从%set中擦除按给定键定位的所有元素。注意,此函数只擦除元素,如果元素本身是指针,则不会以任何方式触及指向的内存。管理指针是用户的责任。

size  求大小

@brief  返回%set的大小。

@return  std::size_t  大小

max_size  最最大大小

@brief  返回%set的最大大小。

@return  std::size_t  大小

begin  获取第一个元素的指针

@brief  返回一个指向%set中第一个元素的只读(常量)迭代器。迭代是按照键的升序进行的。

@return  std::set::iterator  迭代器

end  获取最后一个元素的下一个位置的指针

@brief  返回一个只读(常量)迭代器,指向%set集合中最后一个元素的往下一位置。迭代是按照键的升序进行的。

@return  std::set::iterator  迭代器

find  寻找元素

@brief  试图定位%set中的元素。

@param[in]  要定位的元素。

@return  std::set::iterator  迭代器指向寻找的元素,如果未找到则指向end()。此函数接受一个键并尝试定位与该键匹配的元素。如果成功,则函数返回指向所查找元素的迭代器。如果不成功,则返回end()迭代器。

count  获取指定元素的个数

@brief  查找元素的数量。

@param[in]  被定位的元素。

@return  std::size_t  具有指定键的元素数量。这个函数只对多集有意义;对于set,结果将是0(不存在)或1(存在)。

lower_bound  获取大于等于给定元素的第一个元素指针

@brief  查找匹配给定键的子序列的开头。

@param[in]  要定位的键。

@return  std::set::iterator  指向第一个等于或大于key或end()的元素的迭代器。此函数返回与给定键匹配的子元素序列中的第一个元素。如果不成功,则返回一个迭代器,指向第一个值大于给定key或end()的元素(如果不存在这样的元素)。

upper_bound  获取大于给定元素的第一个元素指针

@brief  查找匹配给定键的子序列的结尾

@param[in]  要定位的键。

@return  std::set::iterator  指向第一个大于key的元素的迭代器,或end()。

clear  擦除所有元素

@brief  擦除%set中的所有元素。注意,这个函数只擦除元素,如果元素本身是指针,则不会以任何方式触及指向的内存。管理指针是用户的责任。

empty  判断集合是否为空

@brief  如果%set为空则返回true。

@return  bool

示例(int类型)

代码

#include 
#include using namespace std;int main()
{std::pair::iterator, bool> temp;int array[] = {1, -1, 2, 3, 3, 2, 2, 1};set set1;for (int i = 0; i < sizeof(array) / sizeof(array[0]); i++){temp = set1.insert(array[i]);if(temp.second)cout << *temp.first << " 插入成功" << endl;elsecout << *temp.first << " 已经存在" << endl;}cout << endl;cout << "set大小为:"<< set1.size() << endl;cout << "set的最大大小为:" << set1.max_size() << endl;cout << endl;cout << "set的元素有:";set::iterator iter = set1.begin();while (iter != set1.end()){cout << *iter << " ";iter++;}cout << endl;cout << endl;set1.erase(1);cout << "使用erase删除元素1后,set的size值为:" << set1.size() <<  endl;cout << endl;iter = set1.find(1);if (iter == set1.end())cout << "1 is not in set!" << endl;elsecout << "1 is in set!" << endl;if(set1.count(1))cout << "1 is in set!" << endl;elsecout << "1 is not in set!" << endl;cout << endl;cout << "大于等于2的元素是" << *set1.lower_bound(2) << endl;cout << "大于2的元素是" << *set1.upper_bound(2) << endl;cout << endl;set1.clear();if (set1.empty()){cout << "set.clear()后,set为空!" << endl;}cout << "set的size值为:" << set1.size() << endl;cout << "set的maxsize的值为:" << set1.max_size() << endl;cout << endl;system("pause");
}

结果

 示例(结构体类型)

注意

需要对 < 重定向

因为set会自动升序,需要告诉其按结构体内哪个值进行升序。

代码

#include 
#include struct Info{int nums;int scope;bool operator < (const Info &x) const{if(scope < x.scope) return true;if(scope == x.scope && nums < x.nums) return true;return false;}
};using namespace std;int main()
{std::pair::iterator, bool> temp;Info info[5] = {{99,2}, {90,1}, {95,3}, {95,3},{89,1}};set set1;for (int i = 0; i < sizeof(info) / sizeof(info[0]); i++){temp = set1.insert(info[i]);if(temp.second)cout << "{" << (*temp.first).nums << ", " << (*temp.first).scope << "}" << " 插入成功" << endl;elsecout << "{" << (*temp.first).nums << ", " << (*temp.first).scope << "}" << " 已经存在" << endl;}cout << endl;cout << "set大小为:"<< set1.size() << endl;cout << "set的最大大小为:" << set1.max_size() << endl;cout << endl;cout << "set的元素有:";set::iterator iter = set1.begin();while (iter != set1.end()){cout << "{" << (*iter).nums << ", " << (*iter).scope << "}" << " ";iter++;}cout << endl;cout << endl;set1.erase(info[1]);cout << "使用erase删除元素{90, 1}后,set的size值为:" << set1.size() <<  endl;cout << endl;iter = set1.find(info[1]);if (iter == set1.end())cout << "{90, 1} is not in set!" << endl;elsecout << "{90, 1} is in set!" << endl;if(set1.count(info[1]))cout << "{90, 1} is in set!" << endl;elsecout << "{90, 1} is not in set!" << endl;cout << endl;Info com = {99, 2};cout << "键值大于等于{99, 2}的元素是" << "{" << (*set1.lower_bound(com)).nums << ", " << (*set1.lower_bound(com)).scope << "}" << endl;cout << "键值大于{99, 2}的元素是" << "{" << (*set1.upper_bound(com)).nums << ", " << (*set1.upper_bound(com)).scope << "}" << endl;com = {0, 2};cout << "键值大于{0, 2}的元素是" << "{" << (*set1.upper_bound(com)).nums << ", " << (*set1.upper_bound(com)).scope << "}" << endl;cout << endl;set1.clear();if (set1.empty()){cout << "set.clear()后,set为空!" << endl;}cout << "set的size值为:" << set1.size() << endl;cout << "set的maxsize的值为:" << set1.max_size() << endl;cout << endl;system("pause");
}

结果

 特别注意

重定向规则会影响查找。

比如lower_bound和upper_bound,示例代码中有例子展示。

而且重定向规则可以使升序排列变成降序排列

相关内容

热门资讯

北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
插入行快捷键 excel添加空... 如下图所示,像这样在两行之间插入多行空白行的操作,你会几种?可能很多人都会觉得,不就是插入空行嘛,简...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
疑难件什么意思 淘宝退货为什么... 01 常见售后类型对于现在主流电商来说,通常支持的售后形式包括仅退款,退货退款,换货,补寄。用户根据...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...