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 5Myset1.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);//查找3if(itr!= Myset1.end())cout<<"在Myset1找到元素3!"<<endl;elsecout<<"在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 ++ << " ";//逆向遍历Myset4cout<<"\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/endfor (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;}
