std::set 是关联容器,含有键值(key)类型对象的已排序集。用比较函数进行排序。搜索、移除和插入拥有对数复杂度。 set 通常以红黑树实现。其定义如下(扒的库):

  1. template<
  2. class Key,
  3. class Compare = std::less<Key>,
  4. class Allocator = std::allocator<Key>
  5. > 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)构造函数:

构造函数有多种实现形式,如下举例:

  1. //四种构造函数形式举例
  2. set<int> Myset1;
  3. int Myint[] = {2,4,6,8,10};
  4. set<int> Myset2(Myint,Myint+5);
  5. set<int> Myset3(Myset2);
  6. set<int> Myset4(Myset2.begin(),Myset2.end());

示例中int是set中数据类型,可以为其他类型,如char,float。
(2)插入数据:

  1. for (int i=1; i<=5; ++i) //插入1 2 3 4 5
  2. Myset1.insert(i);
  3. int Myint3[] = {3,6,9,12,15};
  4. Myset3.insert(Myint3,Myint3+5);

(3)查找元素:
利用find()方法,find()函数返回一个对应查找值迭代器,如果没找到就返回指向set尾部的迭代器。

  1. set<int>::iterator itr;//迭代器
  2. itr = Myset1.find(3);//查找3
  3. if(itr!= Myset1.end())
  4. cout<<"在Myset1找到元素3!"<<endl;
  5. else
  6. cout<<"在Myset1找不到元素3!"<<endl;

(4)元素遍历:
利用迭代器实现,也可以进行逆向遍历。示例如下:

  1. cout<<"\nMyset1中元素内容如下:"<<endl;
  2. for(itr = Myset1.begin();itr!=Myset1.end();itr++)
  3. cout<<*itr<<" ";
  4. cout<<"\nMyset4中元素内容如下:"<<endl;
  5. itr = Myset4.begin();
  6. while(itr != Myset4.end())
  7. cout<<*itr ++ << " ";
  8. //逆向遍历Myset4
  9. cout<<"\nMyset4逆向遍历结果如下:"<<endl;
  10. set<int>::reverse_iterator itr2 = Myset4.rbegin();
  11. while(itr2 != Myset4.rend())
  12. cout<<*itr2++ << " ";
  13. cout<<endl;

(5)元素删除:
采用erase()方法实现:

  1. for(int i = 1;i<=5;i++)
  2. Myset3.erase(i*2);
  3. //或者用itr删除,
  4. itr = Myset4.begin();
  5. itr ++;//此时itr指向第二个元素
  6. Myset4.erase(itr);
  7. //删除多个元素
  8. itr = Myset4.find(6);
  9. Myset4.erase(itr,Myset4.end());

(6)swap()方法:
实现的是对两个set的整体交换。

  1. Myset1.swap(Myset2);

(7)size()方法:
返回set的大小,即元素的个数。

  1. int length1=Myset1.size();

(8)empty()方法
判断set是否为空,若map为空,则返回true。

  1. int length1=Myset1.size();

(9)begin()方法和end()方法:
分别返回指向set头部和尾部的迭代器

  1. // set::begin/end
  2. for (set<int>::iterator it=myset1.begin(); it!=myset1.end(); ++it)
  3. //建立迭代器并循环输出(稍稍有点暴力了)
  4. cout << ' ' << *it;
  5. cout << endl;
  6. // Output:
  7. // 1 2 3 4 5

(10)clear()方法:
清除整个set的内容

  1. Myset1.clear();

5、常见操作程序示例

这里以一道例题举例:L1-020** 帅到没朋友 (20**)
链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805117167976448
代码如下:

  1. #include <iostream>
  2. #include <set>
  3. using namespace std;
  4. int main()
  5. {
  6. int n,t;
  7. set<string> fri;//建立friend对象
  8. string id;
  9. cin>>n;
  10. for(int i = 0; i < n ; i++)
  11. {
  12. cin>>t;
  13. if(t>=2)
  14. {
  15. for(int j = 0; j < t; j++)
  16. {
  17. cin>>id;
  18. fri.insert(id);//储存
  19. }
  20. }
  21. else
  22. {
  23. cin>>id;//防止多余输入
  24. }
  25. }//此处的循环是将前方的朋友圈收纳到已经建立好的friend内部
  26. int c;
  27. cin>>c;
  28. set<string> look;//建立查找对象,当前为空状态
  29. int judge=0;
  30. for(int i = 0;i<c;i++)
  31. {
  32. cin>>id;
  33. if(fri.find(id)==fri.end()&&look.find(id)==look.end())
  34. //查找的发现如果在friend对象中即进行输出,且注意:发现重复后不符合判断规则,仅输出一次
  35. {
  36. look.insert(id);//将查找的朋友放入look对象中防止重复
  37. if(judge==1)
  38. {
  39. cout<<" ";
  40. }
  41. cout<<id;
  42. judge=1;//此处处理空格问题并且标记发现的friend
  43. }
  44. }
  45. if(judge==0)
  46. {
  47. cout<<"No one is handsome"<<endl;
  48. }
  49. return 0;
  50. }