鱼C论坛

 找回密码
 立即注册
查看: 2760|回复: 1

[学习笔记] 050-C++之STL-->set、multiset

[复制链接]
发表于 2018-9-19 23:04:25 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
1、set、multiset简介
1. set是一个集合容器,其中包含的元素是唯一的,集合中旳元素按照一定的顺序排列。
2. set元素的插入过程是按排序规则进行插入(遇到已有元素会插入失败),所以不能指定插入位置。
3. set采用红黑树变体的数据结构实现,红黑树属于平衡二叉树,在插入和删除操作上比vector快。
4. set容器不可以直接存取元素,即不可以使用at(pos)与[]操作。
5. multiset与set的区别: set中每个元素(按排序插入比较的值)只能出现一次,multiset则允许同一个值的多次出现。
6. 不可以直接修改set或multiset容器中的元素值,因为该容器是自动排序的,如果希望修改一个值,必须先删除原有元素,再插入新的元素。

set容器默认排序是由小到大的,即 set<int>  set1;   等价于  set<int, less<int>> set1;
由大到小设置为:set<int, greater<int>> set2;    // #include "functional"

2、set基本操作
insert(n)          插入元素n到集合
clear()        删除set容器中的所有的元素
empty()    判断set容器是否为空   
max_size()    返回set容器可能包含的元素最大个数
size()     返回当前set容器中的元素个数
begin()       返回set容器的第一个迭代器
end()     返回set容器的最后一个元素的后面迭代器
rbegin()    返回的值和end()相同
rend()    返回的值和begin()相同
  1. int main()
  2. {
  3.         set<int> s;
  4.         s.insert(1);
  5.         s.insert(2);
  6.         s.insert(3);
  7.         s.insert(1);
  8.         cout << "set 的 size 值为 :" << s.size() << endl;
  9.         cout << "set 的 maxsize的值为 :" << s.max_size() << endl;
  10.         cout << "set 中的第一个元素是 :" << *s.begin() << endl;
  11.         cout << "set 中的最后一个元素是:" << *(--s.end()) << endl;
  12.         s.clear();
  13.         if (s.empty())
  14.         {
  15.                 cout << "set 为空 !!!" << endl;
  16.         }
  17.         cout << "set 的 size 值为 :" << s.size() << endl;
  18.         cout << "set 的 maxsize的值为 :" << s.max_size() << endl;
  19.         return 0;
  20. }
复制代码

count()         用来查找set中某个某个键值出现的次数
erase(iterator)          删除定位器iterator指向的值
erase(first,second)    删除定位器first和second之间的值
erase(key_value)      删除键值key_value的值

lower_bound(key_value)    返回第一个大于等于key_value的定位器
upper_bound(key_value)   返回最后一个大于等于key_value的定位器
find()    返回给定值值的定位器,如果没找到则返回end()

注意:set中的删除,插入等操作是不进行任何的错误检查的,比如定位器的是否合法等等,所以用的时候自己一定要注意。

3、set容器-复杂类型自定义排序规则
仿函数:重载了operator()运算符的类。
insert(key_value);   ==>   将key_value插入到set中,返回值是pair<set<int>::iterator,bool>,bool标志着插入是否成功,而iterator代表插入的位置,若key_value已经在set中,则iterator表示的key_value在set中的位置。
其中的pair即为一个对组类型。
对组:  两个值封装在一起的一个单元。
pair<T1, T2>  存放两个值的类型,这两个值的类型可以不一样。
        pair.first      是pair类型里的第一个值,类型为T1;
        pair.second  是pair类型里的第二个值,类型为T2.

  1. class Student
  2. {
  3. public:
  4.         Student(char * _name, int _age)
  5.         {
  6.                 strcpy_s(name, _name);
  7.                 age = _age;
  8.         }

  9. public:
  10.         char name[28];
  11.         int age;
  12. };

  13. // 仿函数  (类关键字 class、struct、union)
  14. struct FunStudent
  15. {
  16.         bool operator()(const Student &left, const Student &right)
  17.         {
  18.                 if (left.age < right.age)   // 按照年龄从小到大排列
  19.                 {
  20.                         return true;
  21.                 }
  22.                 else
  23.                 {
  24.                         return false;
  25.                 }
  26.         }
  27. };


  28. int main()
  29. {
  30.         set<Student, FunStudent> set1;

  31.         Student s1("s1", 16);
  32.         Student s2("s1", 15);
  33.         Student s3("s1", 19);
  34.         Student s4("s1", 17);
  35.         Student s5("s8", 15);

  36.         set1.insert(s1);
  37.         set1.insert(s2);
  38.         set1.insert(s3);
  39.         set1.insert(s4);

  40.         // 该函数的返回值是一个对组pair,学会追踪类型    返回结果是一个对组pair
  41.         pair<set<Student, FunStudent>::iterator, bool> pair1 = set1.insert(s5);
  42.         if (pair1.second == true)
  43.         {
  44.                 cout << "插入元素成功\n";
  45.         }
  46.         else
  47.         {
  48.                 cout << "插入元素失败\n";
  49.         }

  50.         for (auto each : set1)
  51.         {
  52.                 cout << each.name << each.age << " ";
  53.         }

  54.         system("pause");
  55.         return 0;
  56. }
复制代码

LAST:multiset容器的操作和set容器是一致的。

本帖被以下淘专辑推荐:

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-4-5 21:06:16 | 显示全部楼层
  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. using namespace std;

  5. int Fivk(int *,int );
  6. double fivk(int *,int *);
  7. int b[2001][3]={{0}};
  8. int main(void)
  9. {
  10.         int n,i,j,m,k,t;
  11.         set<int> a[10000];
  12.         scanf("%d",&n);
  13.         for(i=1;i<=n;i++)
  14.         {
  15.                 scanf("%d",&m);
  16.                 for(j=1;j<=m;j++)
  17.                 {
  18.                         scanf("%d",&t);
  19.                         a[i].insart(t);
  20.                 }
  21.                 b[i][0]=a[i].size();
  22.         }
  23.        
  24.         scanf("%d",&k);
  25.        
  26.         for(i=1;i<=k;i++)
  27.         {
  28.                 scanf("%d %d",&b[i][1],&b[i][2]);
  29.         }
  30.        
  31.         for(i=1;i<=k;i++)
  32.         {
  33.                 m=b[i][1];
  34.                 n=b[i][2];
  35.                 printf("%.2lf%%",100*fivk(a[m].begin,a[n].begin));
  36.                 if(i<k) printf("\n");
  37.         }
  38.         return 0;
  39. }

  40. double fivk(int *a1,int *a2)
  41. {
  42.         int i,j;
  43.         double count=0;
  44.        
  45.         /*for(i=1;i<=a1[0];i++)
  46.         {
  47.                 for(j=1;j<=a2[0];j++)
  48.                 {
  49.                         if(a1[i]==a2[j])
  50.                         {
  51.                                 count++;
  52.                                 break;
  53.                         }
  54.                 }
  55.         }*/
  56.          
  57.         return (double)(count/(a1[0]+a2[0]-count));
  58. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-25 23:52

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表