STL容器之<set>

Posted SiveenWS

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STL容器之<set>相关的知识,希望对你有一定的参考价值。

文章目录

测试环境

系统:ubuntu 22.04.2 LTS 64位
gcc版本:11.3.0
编辑器:vsCode 1.76.2

set介绍

  1. 关联式容器。
  2. 元素是唯一的,即是值又是键。
  3. 元素不能直接修改,需要先删除在插入。
  4. 支持双向迭代器。
  5. 在插入、删除和搜索时间复杂度为log(n)。

头文件

#include <map>

模块类定义

template<typename _Key, typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key> >
    class set;

_Key:表示存储的键数据类型
_Compare:表示按照键的排序方式。
_Alloc:表示所存储分配器的类型,负责元素内存的分配和释放。可选参数,一般不使用。

对象构造

/*默认构造函数*/
std::set<int> set1;
/*构造一个set指定排序方式*/
std::set<int> set2(std::greater<int>());
/*拷贝构造函数*/
std::set<int> set3(set1);
/*移动构造函数*/
std::set<int> set4(std::move(set1));
/*初始化列表*/
std::set<int> set5(5,4,3,2,1);
/*初始化列表+排序方式*/
std::set<int> set6(5,4,3,2,1, std::less<int>());
/*迭代器指定范围构造*/
std::set<int> set7(set6.begin(),set6.end());
/*迭代器指定范围+排序方式*/
std::set<int> set8(set7.begin(), set7.end(), std::less<int>());

初始化

/*初始化列表初始化元素*/
set1 = 1,3,5,4,2;

元素访问

不支持at()函数和下标运算符访问元素

元素插入和删除

函数返回值功能
clear()清空所有元素
erase()迭代器或删除元素数量清除指定位置的一个元素、通过迭代器指定范围内的元素或通过键删除值
emplace()键值对插入元素。插入成功时第一个元素是指向新插入元素的迭代器,失败时第一个元素是指向以存在元素的迭代器,第二个元素表示插入结果,true成功,false失败。
emplace_hint()迭代器插入成功返回新插入元素的迭代器,插入失败时返回已存在元素的迭代器
insert()键值对、迭代器、无1)在指定位置插入1个元素。2)复制通过迭代器指定范围的元素。3)通过初始化列表插入元素。4)直接插入元素。
/*直接构造并插入元素*/
auto ret1 = set1.emplace(10);
std::cout << "result:"<<std::boolalpha<<ret1.second<<std::endl;
std::cout << "value:"<<*(ret1.first)<<std::endl;
/*直接构造元素并插入指定位置*/
auto ret2 = set1.emplace_hint(++set1.begin(),6);
std::cout << "value:"<<*(ret2)<<std::endl;
/*直接构造并在指定位置插入元素*/
auto ret1 = map1.emplace_hint(map1.begin(),1,66);
std::cout << "ret1.first:"<<ret1->first<<" ret1.second:"<<ret1->second<<std::endl;
/*插入元素*/
auto ret3 = set1.insert(8);
std::cout << "result:"<<std::boolalpha<<ret3.second<<std::endl;
std::cout << "value:"<<*(ret3.first)<<std::endl;
/*使用移动函数插入元素*/
int iValue = 7;
auto ret4 = set1.insert(std::move(iValue));
std::cout << "result:"<<std::boolalpha<<ret4.second<<std::endl;
std::cout << "value:"<<*(ret4.first)<<std::endl;
/*指定位置插入元素*/
auto ret5 = set1.insert(++set1.begin(), 12);
std::cout << "value:"<<*(ret5)<<std::endl;
/*使用移动函数在指定位置插入元素*/
int iValue1 = 13;
auto ret6 = set1.insert(--set1.end(), std::move(iValue1));
std::cout << "value:"<<*(ret5)<<std::endl;
/*使用迭代器插入元素*/
set3.insert(++set1.begin(), --set1.end());
/*使用初始化列表插入元素*/
set4.insert(1,2,5,4,8,3);
/*删除指定位置的元素*/
auto ret7 = set4.erase(++set4.begin());
std::cout << "value:"<<*(ret7)<<std::endl;
/*删除指定范围的元素*/
auto ret8 = set4.erase(++set4.begin(), --set4.end());
std::cout << "value:" << *(ret8) << std::endl;
/*按值删除元素*/
int iValue3 = set1.erase(1);
std::cout << "value:" << iValue3 << std::endl;
/*清空元素*/
set3.clear();

元素查找

函数返回值功能
count()std::size_t返回给定键对应元素的数量
find()迭代器查找指定键对应元素的位置,未找到则返回end()
lower_bound()迭代器查找第一个大于或等于给定键的元素的位置,未找到则返回end()
upper_bound()迭代器查找第一个大于给定键的元素的位置,未找到返回end()
equal_range()迭代器获取给定键的lower_bound和upper_bound
/*查找指定值的数量*/
std::cout << "count:" << set1.count(5) << std::endl;
/*查找指定值的位置*/
auto ret9 = set1.find(4);
std::cout << "value:" << *(ret9) << std::endl;
/*查找第一个大于等于给定键的元素的位置*/
auto ret10 = set1.lower_bound(3);
std::cout << "value:"<<*(ret10)<<std::endl;
/*查找第一个大于给定键的元素的位置*/
auto ret11 = set1.upper_bound(2);
std::cout << "value:"<<*(ret11)<<std::endl;
/*分别返回lower_bound和upper_bound*/
auto ret12 = set1.equal_range(1);
std::cout << "lower_bound value:"<<*(ret12.first)<<std::endl;
std::cout << "upper_bound value:"<<*(ret12.second)<<std::endl;

容器大小

函数返回值功能
size()std::size_t获取当前容器中的元素数量
empty()bool判断当前容器是否为空,为空返回true,否则返回false
max_size()std::size_t返回容器的最大容量
/*判断元素的数量*/
std::cout<<set1.size()<<std::endl;
/*判断容器最大能容纳的元素的数量*/
std::cout<<set1.max_size()<<std::endl;
/*判断容器是否为空*/
std::cout<<set1.empty()<<std::endl;/*判断队列中元素数量*/

迭代器

类型功能
iterator正向访问迭代器。从前向后访问元素,可以读取也可以修改
const_iterator常量正向访问迭代器。从前向后访问元素,只能读取不能修改
reverse_iterator逆向访问迭代器。从后向前访问元素,可以读取也可以修改
const_reverse_iterator常量逆向访问迭代器。从后向前访问元素,只能读取不能修改
函数返回值功能
begin()正向访问迭代器返回指向map对象首元素所在位置的迭代器
end()正向访问迭代器返回指向map对象末尾元素的下一个位置的迭代器
cbegin()常量正向访问迭代器返回指向map对象首元素所在位置的常量迭代器
cend()常量正向访问迭代器返回指向map对象末尾元素的下一个位置的迭代器
rbegin()逆向访问迭代器返回指向map对象末尾元素位置的迭代器
rend()逆向访问迭代器返回指向map对象首元素的前一个位置的迭代器
crbegin()常量逆向访问迭代器返回指向map对象末尾元素位置的常量迭代器
crend()常量逆向访问迭代器返回指向map对象首元素的前一个位置的常量迭代器
std::set<int> setTest(1,3,2,6,4,5,8,10,9,7);
/*正向随机访问迭代器,并打印输出(1 2 3 4 5 6 7 8 9 10)*/
std::set<int>::iterator itr;
for (itr = setTest.begin(); itr != setTest.end(); itr++)

    /* 不允许修改元素值 */
    //*itr += 10; 
    /* 访问元素 */
    std::cout<<*(itr)<<" ";

std::cout<<std::endl;
/*常量正向随机访问迭代器,并打印输出(1 2 3 4 5 6 7 8 9 10)*/
std::set<int>::const_iterator cItr;
for (cItr = setTest.cbegin(); cItr != setTest.cend(); cItr++)

    /* 不允许修改值,编译报错 */
    //*cItr += 10; 
    /* 访问元素 */
    std::cout <<*(cItr)<<" ";

std::cout<<std::endl;
/*逆向随机访问迭代器,并打印输出(10 9 8 7 6 5 4 3 2 1)*/
std::set<int>::reverse_iterator rItr;
for (rItr= setTest.rbegin(); rItr!= setTest.rend(); rItr++)

    /* 不允许修改元素值 */
    //*rItr += 100; 
    /* 访问元素 */
    std::cout <<" " << *(rItr);

std::cout<<std::endl;

/*常量逆向随机访问迭代器,并打印输出(10 9 8 7 6 5 4 3 2 1)*/
std::set<int>::const_reverse_iterator crItr;
for (crItr= setTest.crbegin(); crItr!= setTest.crend(); crItr++)

    /* 不允许修改元素值, 编译报错 */
    //*crItr += 100; 
    /* 访问元素 */
    std::cout <<" "<<*crItr;

std::cout << std::endl;

其他函数

函数名返回值功能
swap()交换两个容器的元素
/*交互两个容器元素的值,无返回值*/
std::set<int> setSwap1 = 1,2,3,4,5;
std::set<int> setSwap2 = 6,7,8,9,10;
/*方式1, setSwap1=6,7,8,9,10, setSwap2=1,2,3,4,5*/
setSwap1.swap(setSwap2);
/*setSwap1=1,2,3,4,5, setSwap2=6,7,8,9,10*/
std::swap(setSwap1,setSwap2);

stl之multiset容器的应用

 与set集合容器一样,multiset多重集合容器也使用红黑树组织元素数据,仅仅是multiset容器同意将反复的元素健值插入。而set容器则不同意。

set容器所使用的C++标准头文件set。事实上也是multiset容器的头文件。由于这个set头文件也包括multiset所需的红黑树和自身实现文件。仅仅要用宏语句“#include<set>”包括进来,就可对multiset容器的应用代码进行编译。

创建multiset对象

与set容器一样,multiset容器提供例如以下构造函数。创建multiset对象来管理内部红黑树中的节点元素数据。

1.  set(); 用默认的 less<T>函数对象和内存分配器,创建一个没有不论什么数据元素的 set对象。

2.  set(constkey_compare& comp); 指定一个比較函数对象comp 来创建 set 对象,内存分配器为默认值。

3.  set(constset&);  set拷贝构造函数。通过红黑树的拷贝构造函数。实现两个set容器的元素、头节点和节点个数的拷贝。

4.  set(InputIteratorfirst, InputIteratorlast); 用迭代器区间 [first, last)所指的元素。创建一个 set对象。

5.  set(InputIteratorfirst,InputIterator last, const key_compare& comp);//用迭代器区间 [first, last)所指的元素和comp函数对象,创建一个 set对象。

#include <iostream>
#include <set>
using namespace std;

bool fncomp (int lhs, int rhs) {return lhs<rhs;}

struct classcomp 
{
	bool operator() (const int& lhs, const int& rhs) const
	{return lhs<rhs;}
};
//5种创建multiset对象的方式
int main ()
{
	multiset<int> first;                         
	int myints[]= {10,20,30,20,20};
	multiset<int> second (myints,myints+5);      
	multiset<int> third (second);                
	multiset<int> fourth (second.begin(), second.end()); 
	multiset<int,classcomp> fifth;              
	return 0;
}

元素的插入和删除及搜索

multiset容器元素的插入和删除、搜索与set容器一致,详细能够參考上篇set容器的应用

其它函数

count(); 返回指向某个值元素的个数

#include <iostream>
#include <set>
using namespace std;
int main ()
{
       intmyints[]={10,73,12,22,73,73,12};
       multiset<int>mymultiset (myints,myints+7);
       cout<< "73 appears " << mymultiset.count(73) << "times in mymultiset.\n";
       return0;
}

技术分享

empty(); 假设集合为空,返回true

equal_range(); 返回集合中与给定值相等的上下限的两个迭代器

find(); 返回一个指向被查找到元素的迭代器

get_allocator(); 返回多元集合的分配器

#include <iostream>
#include <set>
using namespace std;
int main ()
{
       multiset<int>mymultiset;
       int* p;
       unsignedint i;
       //用get_allocator申请含义个元素的内存空间
       p=mymultiset.get_allocator().allocate(5);
       //对内存空间进行赋值
       for(i=0; i<5; i++) p[i]=(i+1)*10;
       cout<< "所申请的数组空间包括元素::";
       for(i=0; i<5; i++)
              cout<< ' ' << p[i];
       cout<< '\n';
       //施放内存空间
       mymultiset.get_allocator().deallocate(p,5);
       return0;
}
技术分享

key_comp(); 返回一个用于元素间值比較的函数。默认<

#include <iostream>
#include <set>
using namespace std;
int main ()
{
       multiset<int>mymultiset;
       for(int i=0; i<5; i++)
           mymultiset.insert(i);
       multiset<int>::key_comparemycomp = mymultiset.key_comp();
       cout<< "mymultiset contains:";
       inthighest = *mymultiset.rbegin();
       multiset<int>::iteratorit = mymultiset.begin();
       do{
              std::cout<< ' ' << *it;
       }while ( mycomp(*it++,highest) );
       cout<< '\n';
       return0;
}
技术分享
lower_bound(); 返回指向大于(或等于)某值的第一个元素的迭代器

max_size(); 返回集合能容纳的元素的最大限值

size(); 多元集合中元素的数目

swap(); 交换两个多元集合变量

upper_bound(); 返回一个大于某个值元素的迭代器

value_comp(); 返回一个用于比較元素间的值的函数

转载请注明出处:http://blog.csdn.net/lsh_2013/article/details/46754979,谢谢合作!









以上是关于STL容器之<set>的主要内容,如果未能解决你的问题,请参考以下文章

STL是啥

6-6:STL之map和set

C++ STL常用标准库容器入门(vector,map,set,string,list...)

C++ STL常用标准库容器入门(vector,map,set,string,list...)

6-6-1:STL之map和set——set的基本使用

STL容器之<set>