前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >set用法小结

set用法小结

作者头像
attack
修改2018-04-28 19:43:15
6430
修改2018-04-28 19:43:15
举报

set本质上是一棵红黑树,用法也就那么几个,插入删除lowerbound,再就是跌倒器之类的

基本用法

begin()--返回指向第一个元素的迭代器

代码语言:javascript
复制
#include<cstdio>
#include<set>
int main()
{
    std::set<int>s;
    s.insert(5);
    s.insert(4);
    s.insert(6);
    printf("%d",*s.begin());
    //输出4 
    return 0;
}

end()--返回指向最后一个元素的迭代器

代码语言:javascript
复制
#include<cstdio>
#include<set>
int main()
{
    std::set<int>s;
    s.insert(5);
    s.insert(4);
    s.insert(6);
    printf("%d",*s.end());
    //注意这里的跌倒器指向的是一个空位置!
    //所以最好不要输出end()
    
    //输出末尾元素可以用下面的方法 
    //std::set<int>::iterator it=s.end(); 
    //printf("%d",*--it); 
    return 0;
}

rbegin()--返回指向集合中最后一个元素的反向迭代器

rend()--返回指向集合中第一个元素的反向迭代器

find()--返回一个指向被查找到元素的迭代器

insert()--在集合中插入元素

size()--集合中元素的数目

clear()--清除所有元素

代码语言:javascript
复制
#include<cstdio>
#include<set>
int main()
{
    std::set<int>s;
    s.insert(5);
    s.insert(4);
    s.insert(6);
    printf("%d\n",s.size());
    s.clear();
    printf("%d\n",s.size());
    return 0;
}

count()--返回某个值元素的个数//主要应用于multiset

代码语言:javascript
复制
#include<cstdio>
#include<set>
int main()
{
    std::multiset<int>s;
    s.insert(5);
    s.insert(5);
    s.insert(6);
    printf("%d",s.count(5));
    return 0;
}

empty()--如果集合为空,返回true

erase()--删除集合中的元素

erase可以删除给定的元素,也可以删除跌倒器

在multiset中,删除给定的元素是全部删除,而删除迭代器只会删除一次,下面还会讲到

代码语言:javascript
复制
#include<cstdio>
#include<set>
int main()
{
    std::set<int>s;
    s.insert(5);
    s.insert(4);
    s.insert(6);
    s.erase(5);
    s.erase(s.find(4));
    if(s.find(5)==s.end()) printf("5 is not found\n");
    if(s.find(4)==s.end()) printf("4 is not found\n");
    if(s.find(6)!=s.end()) printf("6 is found");
      return 0;
}

lower_bound()--返回指向大于(或等于)某值的第一个元素的迭代器

代码语言:javascript
复制
#include<cstdio>
#include<set>
int main()
{
    std::set<int>s;
    s.insert(5);
    s.insert(4);
    s.insert(6);
    printf("%d",*s.lower_bound(4));
    //输出为4 
      return 0;
}

upper_bound()--返回大于某个值元素的迭代器

代码语言:javascript
复制
#include<cstdio>
#include<set>
int main()
{
    std::set<int>s;
    s.insert(5);
    s.insert(4);
    s.insert(6);
    printf("%d",*s.upper_bound(4));
    //输出为4 
      return 0;
}

swap()--交换两个集合变量

代码语言:javascript
复制
#include<cstdio>
#include<set>
int main()
{
    std::set<int>s;
    std::set<int>a;
    s.insert(4);
    s.insert(5);
    a.insert(6);
    s.swap(a);
    printf("%d",s.size());
    //输出为1 
      return 0;
}

几个常用操作

正序遍历所有元素

这个需要借助跌倒器来实现

set中是重载了迭代器的++和--运算符的,所以直接使用就可以了

代码语言:javascript
复制
#include<cstdio>
#include<set>
#define sit set<int>::iterator 
using namespace std;
int main()
{
    set<int>s;
    for(int i=1;i<=10;i++) 
        s.insert(i);
    for(sit i=s.begin();i!=s.end();i++)
        printf("%d ",*i);
    //输出1 2 3 4 5 6 7 8 9 10 
    return 0;
}

倒序遍历所有元素

可以使用rbegin和rend实现,他们与begin和end的关系如下图所示

代码语言:javascript
复制
#include<cstdio>
#include<set>
#define rsit set<int>::reverse_iterator 
using namespace std;
int main()
{
    set<int>s;
    for(int i=1;i<=10;i++) 
        s.insert(i);
    rsit it=s.rbegin();
    for(rsit i=s.rbegin();i!=s.rend();i++)
        printf("%d ",*i);
    //输出10 9 8 7 6 5 4 3 2 1
    return 0;
}

multiset中删除元素

在multiset中,如果仅仅用erase($x$)来删除$x$元素,那么$x$的出现次数会变为$0$

解决方法是先找到$x$对应的迭代器,然后将迭代器删除,这样就可以使$x$只删除一次

代码语言:javascript
复制
#include<cstdio>
#include<set>
#define sit set<int>::iterator 
using namespace std;
int main()
{
    multiset<int>s;
    s.insert(2);
    s.insert(2);
    s.insert(2);
    s.erase(2);
    printf("%d\n",s.count(2));
    
    s.insert(2);
    s.insert(2);
    s.insert(2);
    s.erase(s.find(2));
    printf("%d\n",s.count(2));
    //输出0 2 
    return 0;
}

自定义排序规则

如果元素不在结构体中,需要自定义结构体并重载“$()$”运算符

代码语言:javascript
复制
#include<cstdio>
#include<set>
#define sit set<int>::iterator 
using namespace std;
struct comp
{
    bool operator ()(const int &a,const int &b)
    {
        return a>b;
    }
};
int main()
{
    set<int,comp>s;
    for(int i=1;i<=10;i++) 
        s.insert(i);
    for(sit i=s.begin();i!=s.end();i++)
        printf("%d ",*i);
    //输出10 9 8 7 6 5 4 3 2 1 
    return 0;
}

若元素在结构体中,则需要重载$<$运算符

代码语言:javascript
复制
#include<cstdio>
#include<set>
#define sit set<node>::iterator 
using namespace std;
struct node
{
    int l,r;
    node(int l=0,int r=0):l(l),r(r){};
    bool operator < (const node &a) const
    {
        return r==a.r?l<a.l:r<a.r;
    }
};
int main()
{
    set<node>s;
    for(int i=1;i<=10;i++) 
        s.insert(node(i,10-i+1));
    for(sit i=s.begin();i!=s.end();i++)
        printf("%d %d\n",i->l,i->r);
        
    //输出
    /*
    10 1
    9 2
    8 3
    7 4
    6 5
    5 6
    4 7
    3 8
    2 9
    1 10
    */
    return 0;
}

在结构体中二分

只要重载了$<$,就可以在结构体中二分了

代码语言:javascript
复制
#include<cstdio>
#include<set>
#define sit set<node>::iterator 
using namespace std;
struct node
{
    int l,r;
    node(int l=0,int r=0):l(l),r(r){};
    bool operator < (const node &a) const
    {
        return r==a.r?l<a.l:r<a.r;
    }
};
int main()
{
    set<node>s;
    for(int i=1;i<=10;i++) 
        s.insert(node(i,i));
    sit it=s.lower_bound(node(1,2));
    printf("%d %d",it->l,it->r);
        
    //输出 2 2
    return 0;
}

题目

都是可以用set水的大水题

BZOJ2783

BZOJ2028

BZOJ1058

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-04-02 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 基本用法
  • 几个常用操作
    • 正序遍历所有元素
      • 倒序遍历所有元素
        • multiset中删除元素
          • 自定义排序规则
            • 在结构体中二分
            • 题目
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档