原地址:http://blog.csdn.net/chaiwenjun000/article/details/50561775

SET 集合

百度百科中说集合中的元素有三个特征:

1.确定性(集合中的元素必须是确定的) 2.互异性(集合中的元素互不相同。例如:集合A={1,a},则a不能等于1) 3.无序性(集合中的元素没有先后之分。)

而STL中的集合set ,按照定义保证了元素的确定性,互异性,神奇的是其中的元素却是有序的

卓越的前辈们在c++里为我们封装好了set,只需要在头文件里

[cpp] view plain copy

 

  1. #include<set>
  2. using namespace std;

就可以方便的使用了。

如何定义一个set?

[cpp] view plain copy

 

  1. set<_type> _name;
  2. _type集合元素的类型 ,除了基本类型也可以是自定义类型。
  3. _name 该集合的名称

我们以int为例做一下示范

先介绍几个set常用的函数
.insert(v) //插入一个元素v
.erase(v) //删除一个元素v (可以是元素的值,也可以是迭代器(后面会有介绍))
.empty() //判断是否为空
.count(v)//判断 v出现了几次

[cpp] view plain copy

 

  1. #include<set>
  2. using namespace std;
  3. int main(){
  4. set<int>st; //定义了一个int类型的集合,名称为st
  5. st.insert(1); st.insert(7);    st.insert(4);
  6. if(!st.empty())
  7. printf("yes\n");
  8. if(st.count(1)) printf("1yes\n"); else printf("1no\n");
  9. if(st.count(2)) printf("2yes"); else printf("2no\n");
  10. }

SET的应用

有了这几个函数,set就可以做很多事了,其中最常用的就是 判断一个数是否出现过。 
set内部使用红黑树实现,也就是平衡的二叉树查找树,其插入删除查找的效率是稳定的O(logn)。这个效率是很高的,当然设计合适的hash函数速度更快O(1),但对于一般的问题这个已经足够了,而且简单书写。

下面就以昨天CF第三题为例做下示范
http://codeforces.com/contest/620/problem/C

长度为n的珠子链, 从左到右位置标号1~n, 每个位置的珠子可能有不同的种类,
规定连续的一段中如果存在两个珠子种类相同,则称为好珠子段,问最多有多少好珠子段,并打印段的位置。

方法
直接贪心,遇到两个相同的珠子,就记录下来位置。然后将之前的标记清空。
标记方法?  ai 范围 1≤ ai ≤ 10^9,开那么大的数组显然不行,而且清空也麻烦
直接用set即可!

[cpp] view plain copy

 

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <set>
  6. using namespace std;
  7. const int maxn = 100000*4;
  8. int arr[maxn];
  9. int cnt[maxn];
  10. set<int>st;
  11. int main()
  12. {
  13. int t;
  14. scanf("%d",&t);
  15. int c = 0;
  16. for(int i=0;i<t;i++){
  17. scanf("%d",&arr[i]);
  18. if(!st.count(arr[i])) //没有标记过的
  19. st.insert(arr[i]);
  20. else
  21. {
  22. st.clear(); //清空set
  23. cnt[c++] = i+1; //记录标记的位置(出现第二次的珠子位置)
  24. }
  25. }
  26. cnt[c-1] = t;
  27. if(c == 0)
  28. printf("-1\n");
  29. else{
  30. printf("%d\n",c);
  31. int l = 1;
  32. for(int i=0;i<c;i++){
  33. printf("%d %d\n",l,cnt[i]);
  34. l = cnt[i]+1;
  35. }
  36. }
  37. return 0;
  38. }

SET的遍历

这里用到了迭代器的相关知识,学完C++后再去深究,这里知道怎么用就行了。

前面说了set中的元素是有序的,那么我们来遍历一下。

[cpp] view plain copy

 

  1. #include<set>
  2. using namespace std;
  3. int main(){
  4. set<int>st; //定义了一个int类型的集合,名称为st
  5. st.insert(1); st.insert(7);    st.insert(4);
  6. st.insert(0);
  7. for(set<int>::iterator it = st.begin();it!=st.end();++it){
  8. printf("%d ",*it);
  9. }
  10. }
  11. 可以看出迭代器的使用和指针类似 , 也是通过解引用运算符 *it来获取值,也可以通过++ -- 移动。
  12. 也可以单个取出元素
  13. set<int>::iterator it = st.begin();
  14. printf("%d\n",*it);
  15. 注意这里的.begin()代表了set中的首元素位置,而.end()代表的是尾元素位置的下一个位置。
  16. STL中很多容器都是这样的左闭右开区间,不用去深究。

SET 集合

百度百科中说集合中的元素有三个特征:

1.确定性(集合中的元素必须是确定的) 2.互异性(集合中的元素互不相同。例如:集合A={1,a},则a不能等于1) 3.无序性(集合中的元素没有先后之分。)

而STL中的集合set ,按照定义保证了元素的确定性,互异性,神奇的是其中的元素却是有序的

卓越的前辈们在c++里为我们封装好了set,只需要在头文件里

[cpp] view plain copy

 

  1. #include<set>
  2. using namespace std;

就可以方便的使用了。

如何定义一个set?

[cpp] view plain copy

 

  1. set<_type> _name;
  2. _type集合元素的类型 ,除了基本类型也可以是自定义类型。
  3. _name 该集合的名称

我们以int为例做一下示范

先介绍几个set常用的函数
.insert(v) //插入一个元素v
.erase(v) //删除一个元素v (可以是元素的值,也可以是迭代器(后面会有介绍))
.empty() //判断是否为空
.count(v)//判断 v出现了几次

[cpp] view plain copy

 

  1. #include<set>
  2. using namespace std;
  3. int main(){
  4. set<int>st; //定义了一个int类型的集合,名称为st
  5. st.insert(1); st.insert(7);    st.insert(4);
  6. if(!st.empty())
  7. printf("yes\n");
  8. if(st.count(1)) printf("1yes\n"); else printf("1no\n");
  9. if(st.count(2)) printf("2yes"); else printf("2no\n");
  10. }

SET的应用

有了这几个函数,set就可以做很多事了,其中最常用的就是 判断一个数是否出现过。 
set内部使用红黑树实现,也就是平衡的二叉树查找树,其插入删除查找的效率是稳定的O(logn)。这个效率是很高的,当然设计合适的hash函数速度更快O(1),但对于一般的问题这个已经足够了,而且简单书写。

下面就以昨天CF第三题为例做下示范
http://codeforces.com/contest/620/problem/C

长度为n的珠子链, 从左到右位置标号1~n, 每个位置的珠子可能有不同的种类,
规定连续的一段中如果存在两个珠子种类相同,则称为好珠子段,问最多有多少好珠子段,并打印段的位置。

方法
直接贪心,遇到两个相同的珠子,就记录下来位置。然后将之前的标记清空。
标记方法?  ai 范围 1≤ ai ≤ 10^9,开那么大的数组显然不行,而且清空也麻烦
直接用set即可!

[cpp] view plain copy

 

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <set>
  6. using namespace std;
  7. const int maxn = 100000*4;
  8. int arr[maxn];
  9. int cnt[maxn];
  10. set<int>st;
  11. int main()
  12. {
  13. int t;
  14. scanf("%d",&t);
  15. int c = 0;
  16. for(int i=0;i<t;i++){
  17. scanf("%d",&arr[i]);
  18. if(!st.count(arr[i])) //没有标记过的
  19. st.insert(arr[i]);
  20. else
  21. {
  22. st.clear(); //清空set
  23. cnt[c++] = i+1; //记录标记的位置(出现第二次的珠子位置)
  24. }
  25. }
  26. cnt[c-1] = t;
  27. if(c == 0)
  28. printf("-1\n");
  29. else{
  30. printf("%d\n",c);
  31. int l = 1;
  32. for(int i=0;i<c;i++){
  33. printf("%d %d\n",l,cnt[i]);
  34. l = cnt[i]+1;
  35. }
  36. }
  37. return 0;
  38. }

SET的遍历

这里用到了迭代器的相关知识,学完C++后再去深究,这里知道怎么用就行了。

前面说了set中的元素是有序的,那么我们来遍历一下。

[cpp] view plain copy

 

  1. #include<set>
  2. using namespace std;
  3. int main(){
  4. set<int>st; //定义了一个int类型的集合,名称为st
  5. st.insert(1); st.insert(7);    st.insert(4);
  6. st.insert(0);
  7. for(set<int>::iterator it = st.begin();it!=st.end();++it){
  8. printf("%d ",*it);
  9. }
  10. }
  11. 可以看出迭代器的使用和指针类似 , 也是通过解引用运算符 *it来获取值,也可以通过++ -- 移动。
  12. 也可以单个取出元素
  13. set<int>::iterator it = st.begin();
  14. printf("%d\n",*it);
  15. 注意这里的.begin()代表了set中的首元素位置,而.end()代表的是尾元素位置的下一个位置。
  16. STL中很多容器都是这样的左闭右开区间,不用去深究。

(转)set集合的用法的更多相关文章

  1. 关于comparable与comparator的用法(即自定义集合框架用法 )

    package javastudy; import java.util.Comparator; import java.util.Iterator; import java.util.TreeSet; ...

  2. C++ set集合容器用法解析

    1.简介 set是C++STL库中的一个容器,他十分的便利,所有的元素插入时都会被自动排序,并且容器内保证元素不重复,就想高一数学中讲的集合具有互异性一样,(好像set本来就叫集合容器 bushi)2 ...

  3. Delphi集合的用法

    参考:http://www.cnblogs.com/doit8791/archive/2012/08/17/2644859.html 集合是Pascal特有的数据类型,在Visual Basic.C/ ...

  4. set集合的用法总结(转)

    python的set和其他语言类似, 是一个无序不重复元素集, 基本功能包括关系测试和消除重复元素. 集合对象还支持union(联合), intersection(交), difference(差)和 ...

  5. UICollectionView 集合视图用法,自定义Cell

    在View里面 //1.创建UICollectionViewFlowLayout UICollectionViewFlowLayout *flowLayout=[[UICollectionViewFl ...

  6. delphi 集合的用法

    http://blog.sina.com.cn/s/blog_9e2e8405010180jy.html delphi基础补充     1 开域语句     在面向对象的程序代码中,嵌套对象的现象十分 ...

  7. 认识python中的set集合及其用法

    python中,集合(set)是一个无序排列,可哈希, 支持集合关系测试,不支持索引和切片操作,没有特定语法格式, 只能通过工厂函数创建.集合里不会出现两个相同的元素, 所以集合常用来对字符串或元组或 ...

  8. remove集合的用法

    循环集合的方法有三种: 简单for循环 iterator循环 增强for循环 例子如下: List<Long> fList = new ArrayList<Long>(); f ...

  9. Python中字典和集合的用法

    本人开始学习python 希望能够慢慢的记录下去 写下来只是为了害怕自己忘记. python中的字典和其他语言一样 也是key-value的形式  利用空间换时间 可以进行快速的查找 key 是唯一的 ...

随机推荐

  1. ubuntu10.04+win7双系统,重装win7后,恢复grub引导菜单以及命令行引导linux

    我在我的小Y上安装了ubuntu10.04和win7旗舰版的双系统,采用的是grub引导.今天win7不知道哪儿出了问题,windows update更新一直报错,(当然360也是打不上滴)网上查了很 ...

  2. RecyclerView的万能分割线

    效果图: 使用方法: 添加默认分割线:高度为2px,颜色为灰色 mRecyclerView.addItemDecoration(new RecyclerViewDivider(mContext, Li ...

  3. 【leetcode】Spiral Matrix II (middle)

    Given an integer n, generate a square matrix filled with elements from 1 to n2 in spiral order. For ...

  4. VS工程目标文件名设置

    默认的输出文件名是$(ProjectName) 可以在项目属性-配置属性-常规-目标文件名中设置 例如我想在Debug版本的输出文件加一个后缀d,那么我可以这样设置:$(ProjectName)d

  5. osg绘制一个球体

    //By smells2 at Lab 2012-02-21#include <osg/Group>#include <osg/Geode>#include <osg/S ...

  6. Android笔记:ninepatch

    上边框和左边框绘制的部分就表示当图片需要拉伸时就拉伸黑点标记的区域 下边框和右边框绘制的部分则表示内容会被放置的区域

  7. September 21st 2016 Week 39th Wednesday

    Don't try so hard, the best things come when you least expect them. 不要着急,最好的总会在最不经意的时候出现. Always tur ...

  8. Rabbitmq实现负载均衡与消息持久化

      Rabbitmq 是对AMQP协议的一种实现.使用范围也比较广泛,主要用于消息异步通讯. 一,默认情况下Rabbitmq使用轮询(round-robin)方式转发消息.为了较好实现负载,可以在消息 ...

  9. vector reserve与resize区别

    vector 的reserve增加了vector的capacity,但是它的size没有改变!而resize改变了vector的capacity同时也增加了它的size!原因如下:reserve是容器 ...

  10. Codeforces Round #344 (Div. 2)(按位或运算)

    Blake is a CEO of a large company called "Blake Technologies". He loves his company very m ...