• STL整理之set


    转载请注明出处,部分内容引自李煜东《算法竞赛进阶指南》


    前置知识: C++、C语言入门


    Set是什么

    Set是C++STL中提供的容器, tset 是数学上的集合——具有唯一性,即每个元素只出现一次,而 multiset 则是可重集,两者的内部实现是一棵红黑树,它们支持的函数基本相同。set用于判断一个集合内元素的有无。

    Set的相关操作

    头文件与声明

    像这样:

    #include<set>
    set<类型>名称;
    
    //example:
    
    set<int>s;
    set<vector<int> >s;     //vector中提供重载<
    set<set<int> >s;    //平衡树嵌套,哈哈
    multiset<double>s;

     

    就像其他需要排序的数据类型一样,为一个结构体的 set ,需要重载小于号

    struct node{
        ......;
    };
    set<node>s;
    bool operator <(const node &ai,const node &bi)
    {
        return ai.x>bi.x;
    }

    set.size()

    统计 set 中元素个数,函数返回一个整形变量,表示 set 中元素个数,时间复杂度O(1)

    用法:名称.size();
    eg.
    int num=s.size();

    set.empty()

    检查 set 是否为空,返回一个 bool 型变量,1表示 set 为空,否则为非空,时间复杂度O(1)

    用法:名称.empty();
    eg.
    if(s.empty())
        cout<<"Myset is Empty."<<endl;

    set.clear()

    清空 setset ,无返回值

    用法:名称.clear();
    eg.
    int num=s.clear();

    set.count(x)

    返回 set 或 multiset 中值为 x 的元素个数,时间复杂度为 O(logn)

    用法:名称.count(x)
    eg.
    if(!s.count(x))
        ans++;

    迭代器

    1. 双向访问迭代器,不支持随机访问,支持星号解除引用,仅支持“++”,“--”这两个算术操作

    引用和操作:

    set<int>::iterator it=s.begin(); it++; it--;

    若把 it++ ,则 it 将会指向“下一个”元素。这里的下一个是指在 key 从小到大排序的结果中,排在 it 下一名的元素。同理,若把 it-- ,则 it 会指向排在上一个的元素

    “++”,“--”操作的复杂度均为 O(log n)

    1. 遍历 set 及访问其中的元素
    for(set<int>::iterator it=s.begin();it!=s.end();it++)
        cout<<*it<<endl;    //取出这个迭代器指向的元素
    //set嵌套
    for(set<set<int> >::iterator it=s.begin();it!=s.end();it++)
    {
        //首先取出set中嵌套的set
        for(set<int>::iterator rit=(*it).begin();rit!=(*it).end();rit++)
            cout<<*rit<<' ';    //遍历这个set
        cout<<endl;
    }

    set.begin()

    返回集合的首迭代器,即指向集合中最小元素的迭代器,时间复杂度为 O(1)

    用法:名称.begin();
    eg.
    set<int>::iterator it=s.begin();

    set.end()

    返回集合的尾迭代器,众所周知,STL中区间都是左闭右开的,那么 end() 函数返回的迭代器即为指向集合中最大元素的下一个位置的迭代器,因此 --s.end() 

    才是指向集合中最大元素的迭代器,时间复杂度为 O(1)

    用法:名称.end();
    eg.
    maxn=*(--s.end());      //取出最大元素

    set.insert(x)

    在 set 中插入元素,返回插入地址的迭代器和是否插入成功的 bool 并成的 pair ,时间复杂度为 O(logn)

    PS: set 在进行插入的时候是不允许有重复的键值的,如果新插入的键值与原有的键值重复则插入无效( multiset可以重复)

    用法:名称.insert(set类型);
    eg.
    s.insert(3);

    set.erase(参数)

    删除,参数可以是元素或者迭代器,返回下一个元素的迭代器,时间复杂度为 O(log n) ,注意在 multiset 中 s.erase(x) 会删除所有值为 x 的元素

    用法:名称.erase(参数);
    eg.
    set<int>::iterator it=s.begin();
    s.erase(it);
    s.erase(3);

    set.find(x)

    在 set 中查找值为 xx 的元素,并返回指向该元素的迭代器,若不存在,返回 set.end() ,时间复杂度为 O(logn)

    用法:名称.find(x);
    eg.
    if(s.find(x)!=s.end())
        cout<<"Have Found!"<<endl;

    set.lower_bound(x)/upper_bound(x)

    两个神奇的东西,决定把他们放在一块谈一谈

    用法与 find 类似,但查找的条件略有不同,时间复杂度 O(log n)

    s.lower _ bound(x) 表示查找 >=x 的元素中最小的一个,并返回指向该元素的迭代器

    s.upper _ bound(x) 表示查找 >x 的元素中最小的一个,并返回指向该元素的迭代器

    举个例子:

    在 set { 3,5,7,8,13,13,5,7,8,13,16 }中

    对于在 set 中存在的元素,比如8

    s.lower _ bound(8) 返回8所在位置的迭代器

    s.upper _ bound(8) 返回13所在位置的迭代器

    对于在 set 中不存在的元素,比如12

    两个函数返回的则都是13所在位置的迭代器

    特殊地,

    对于比 set 中最大的元素大的元素,比如20

    两个函数返回的都是 s.end()

    转自洛谷日报https://www.luogu.org/blog/communist/stl-zheng-li-zhi-set

  • 相关阅读:
    安卓开发学习笔记(七):仿写腾讯QQ登录注册界面
    android studio 撤销和恢复
    安卓开发学习笔记(六):如何实现指定图片定时开屏功能?
    JAVA小白开发环境配置(编译器为Idea)
    我的博客即将入驻“云栖社区”,诚邀技术同仁一同入驻。
    安卓开发学习笔记(五):史上最简单且华丽地实现Android Stutio当中Webview控件https/http协议的方法
    安卓开发学习笔记(四):Android Stuidio无法实现隐式Intent是为什么?
    XML如何添加注释?
    安卓开发学习笔记(三):Android Stuidio无法引用Intent来创建对象,出现cannot resolve xxx
    安卓开发学习笔记(二):如何用Android Stuidio在res资源下创建xml视图文件
  • 原文地址:https://www.cnblogs.com/xxzh/p/9327118.html
Copyright © 2020-2023  润新知