std::set 是关联容器,含有键值(key)类型对象的已排序集。用比较函数进行排序。搜索、移除和插入拥有对数复杂度。 set 通常以红黑树实现。其定义如下(扒的库):
template<
class Key,
class Compare = std::less<Key>,
class Allocator = std::allocator<Key>
> class set;
2、set的常见操作
成员函数
成员函数 | 作用 |
---|---|
(构造函数) | 构造 set |
(析构函数) | 析构 set |
operator= | 赋值给容器 |
1、迭代器
begin() cbegin() |
返回指向容器第一个元素的迭代器 |
---|---|
end() cend() |
返回指向容器尾端的迭代器 |
rbegin() crbegin() |
返回一个指向容器最后一个元素的反向迭代器 |
rend() crend() |
返回一个指向容器前端的反向迭代器 |
2、容量
empty() | 检查容器是否为空,元素数为0时返回true,否则返回false |
---|---|
size() | 返回容纳的元素数 |
max_size() | 返回可容纳的最大元素数 |
3、修改器
clear() | 清除内容 |
---|---|
4、查找
count( const Key& key ) const | 返回匹配特定键的元素数量 |
---|---|
find( const Key& key ) | 寻找带有特定键的元素 |
equal_range( const Key& key ) | 返回匹配特定键的元素范围 |
lower_bound( const Key& key ) | 返回指向首个不小于给定键的元素的迭代器 |
upper_bound( const Key& key ) | 返回指向首个大于给定键的元素的迭代器 |
当然,关于set的操作还有很多,下列列举出常见的用法:
(1)构造函数:
构造函数有多种实现形式,如下举例:
//四种构造函数形式举例
set<int> Myset1;
int Myint[] = {2,4,6,8,10};
set<int> Myset2(Myint,Myint+5);
set<int> Myset3(Myset2);
set<int> Myset4(Myset2.begin(),Myset2.end());
示例中int是set中数据类型,可以为其他类型,如char,float。
(2)插入数据:
for (int i=1; i<=5; ++i) //插入1 2 3 4 5
Myset1.insert(i);
int Myint3[] = {3,6,9,12,15};
Myset3.insert(Myint3,Myint3+5);
(3)查找元素:
利用find()方法,find()函数返回一个对应查找值迭代器,如果没找到就返回指向set尾部的迭代器。
set<int>::iterator itr;//迭代器
itr = Myset1.find(3);//查找3
if(itr!= Myset1.end())
cout<<"在Myset1找到元素3!"<<endl;
else
cout<<"在Myset1找不到元素3!"<<endl;
(4)元素遍历:
利用迭代器实现,也可以进行逆向遍历。示例如下:
cout<<"\nMyset1中元素内容如下:"<<endl;
for(itr = Myset1.begin();itr!=Myset1.end();itr++)
cout<<*itr<<" ";
cout<<"\nMyset4中元素内容如下:"<<endl;
itr = Myset4.begin();
while(itr != Myset4.end())
cout<<*itr ++ << " ";
//逆向遍历Myset4
cout<<"\nMyset4逆向遍历结果如下:"<<endl;
set<int>::reverse_iterator itr2 = Myset4.rbegin();
while(itr2 != Myset4.rend())
cout<<*itr2++ << " ";
cout<<endl;
(5)元素删除:
采用erase()方法实现:
for(int i = 1;i<=5;i++)
Myset3.erase(i*2);
//或者用itr删除,
itr = Myset4.begin();
itr ++;//此时itr指向第二个元素
Myset4.erase(itr);
//删除多个元素
itr = Myset4.find(6);
Myset4.erase(itr,Myset4.end());
(6)swap()方法:
实现的是对两个set的整体交换。
Myset1.swap(Myset2);
(7)size()方法:
返回set的大小,即元素的个数。
int length1=Myset1.size();
(8)empty()方法
判断set是否为空,若map为空,则返回true。
int length1=Myset1.size();
(9)begin()方法和end()方法:
分别返回指向set头部和尾部的迭代器
// set::begin/end
for (set<int>::iterator it=myset1.begin(); it!=myset1.end(); ++it)
//建立迭代器并循环输出(稍稍有点暴力了)
cout << ' ' << *it;
cout << endl;
// Output:
// 1 2 3 4 5
(10)clear()方法:
清除整个set的内容
Myset1.clear();
5、常见操作程序示例
这里以一道例题举例:L1-020** 帅到没朋友 (20分**)
链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805117167976448
代码如下:
#include <iostream>
#include <set>
using namespace std;
int main()
{
int n,t;
set<string> fri;//建立friend对象
string id;
cin>>n;
for(int i = 0; i < n ; i++)
{
cin>>t;
if(t>=2)
{
for(int j = 0; j < t; j++)
{
cin>>id;
fri.insert(id);//储存
}
}
else
{
cin>>id;//防止多余输入
}
}//此处的循环是将前方的朋友圈收纳到已经建立好的friend内部
int c;
cin>>c;
set<string> look;//建立查找对象,当前为空状态
int judge=0;
for(int i = 0;i<c;i++)
{
cin>>id;
if(fri.find(id)==fri.end()&&look.find(id)==look.end())
//查找的发现如果在friend对象中即进行输出,且注意:发现重复后不符合判断规则,仅输出一次
{
look.insert(id);//将查找的朋友放入look对象中防止重复
if(judge==1)
{
cout<<" ";
}
cout<<id;
judge=1;//此处处理空格问题并且标记发现的friend
}
}
if(judge==0)
{
cout<<"No one is handsome"<<endl;
}
return 0;
}