set用法小結

set本質上是一棵紅黑樹,用法也就那麼幾個,插入刪除lowerbound,再就是迭代器之類的html

基本用法

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

#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;
}
begin()

end()--返回指向最後一個元素的迭代器ide

#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;
}
end()

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

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

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

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

size()--集合中元素的數目blog

clear()--清除全部元素排序

#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;
}
clear()

count()--返回某個值元素的個數//主要應用於multisetget

#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;
}
count

empty()--若是集合爲空,返回true

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

erase能夠刪除給定的元素,也能夠刪除迭代器

在multiset中,刪除給定的元素是所有刪除,而刪除迭代器只會刪除一次,下面還會講到

#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;
}
erase()

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

#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;
}
lower_bound()

upper_bound()--返回大於某個值元素的迭代器

#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;
}
upper_bound()

swap()--交換兩個集合變量

#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;
}
swap()

幾個經常使用操做

正序遍歷全部元素

這個須要藉助迭代器來實現

set中是重載了迭代器的++和--運算符的,因此直接使用就能夠了

 

#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的關係以下圖所示

 

#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$只刪除一次

#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;
}

自定義排序規則

若是元素不在結構體中,須要自定義結構體並重載「$()$」運算符

#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;
}

若元素在結構體中,則須要重載$<$運算符

#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;
}

 

在結構體中二分

只要重載了$<$,就能夠在結構體中二分了

#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

相關文章
相關標籤/搜索