set集合容器:

调用头文件:

#include<set>

using namespace std;

详细用法(部分):

set<int> t      ------      定义一个int类型的容器,注意set里的每个元素只会出现1次

t.insert(k)      ------      插入元素k,多次插入同一个元素后面无效

t.count(k)      ------      判断元素k是否在容器内

t.erase(k)

t,clear()      ------      清空容器

t.size()      ------      返回容器现有元素个数

t.empty()      ------      判断容器是否为空




想遍历set里的元素或进行进一步修改,必须定义对应迭代器,以下三种定义方法(迭代器类似于指针)

set<int>::iterator it      ------      定义正向迭代器

set<int>::reverse_iterator rit;      ------      定义反向迭代器

auto it = t.begin();      ------      因为t.begin()返回正向迭代器,所以it自动被定义为正向迭代器,可适应其他所有操作

以下需要迭代器的操作:

t.begin()      ------      返回set中第一个元素,类型为正向迭代器

t.rbegin()      ------      返回set中最后一个元素,类型为反向迭代器

t.end()      ------返回set中最后一个元素,类型为正向迭代器

t.rend()      ------      返回set中第一个元素,类型为反向迭代器




t.find(k)      ------      寻找k,若找到返回对应的迭代器,否则返回end();

t,insert(a, b)      ------      插入指针[a, b)之间的元素,已有元素不会再次插入

t.erase(it)      ------      删除迭代器it对应的元素

t.erase(l, r)      ------      删除迭代器[l, r)之间的元素

lower_bound(k)      ------      返回第一个大于等于k的元素的迭代器

upper_bound(k)      ------      对于set这种元素唯一的容器,该操作与lower_bound(k)相同,只有一种情况不同,就是

容器中若含有元素k,该操作会返回k下一个元素的迭代器


#include<stdio.h>  
#include<set>
using namespace std;
set<int> t;
int main(void)
{
t.insert(5);
t.insert(3);
t.insert(8);
t.insert(9);
t.insert(12);
printf("the size is %d\n", t.size());
printf("%d %d\n", t.count(5), t.count(-1)); //运行结果:1 0

set<int>::iterator it;
for(it=t.begin();it!=t.end();it++) //运行结果:3 5 8 9 12
printf("%d ", *it);
printf("\n");

set<int>::reverse_iterator rit;
for(rit=t.rbegin();rit!=t.rend();rit++) //运行结果:12 9 8 5 3
printf("%d ", *rit);
printf("\n");

auto a = t.begin();
auto b = t.begin();
b++;
t.erase(a,b);
for(it=t.begin();it!=t.end();it++) //运行结果:5 8 9 12
printf("%d ", *it);
printf("\n");

a = t.lower_bound(6);
b = t.upper_bound(8);
printf("%d %d\n", *a, *b); //运行结果:8 9
return 0;
}





1.创建set集合对象


#include<iostream>  
#include<set>
using namespace std;
int main()
{
int> s;
return 0;
}

2.元素的插入与中序遍历


        采用inset()方法把元素插入到集合中,插入规则在默认的比较规则下,是按元素值从小到大插入,如果自己指定了比较规则函数,则按自定义比较规则函数插入。使用前向迭代器对集合中序遍历,结果正好是元素排序后的结果。


#include<iostream>  
#include<set>
using namespace std;
int main()
{
int> s;
//第一次插入5,可以插入
s.insert(1);
s.insert(6);
s.insert(3);
//第二次插入5,重复元素,不会插入
int>::iterator it; //定义前向迭代器
//中序遍历集合中的所有元素
for(it = s.begin(); it != s.end(); it++)
{
" ";
}
cout << endl;
return 0;
}
//运行结果:1 3 5 6

3.元素的方向遍历

#include<iostream>  
#include<set>
using namespace std;
int main()
{
int> s;
//第一次插入5,可以插入
s.insert(1);
s.insert(6);
s.insert(3);
//第二次插入5,重复元素,不会插入
int>::reverse_iterator rit; //定义反向迭代器
//反向遍历集合中的所有元素
for(rit = s.rbegin(); rit != s.rend(); rit++)
{
" ";
}
cout << endl;
return 0;
}
//运行结果:6 5 3 1


4.元素的删除

#include<iostream>  
#include<set>
using namespace std;
int main()
{
int> s;
//第一次插入5,可以插入
s.insert(1);
s.insert(6);
s.insert(3);
//第二次插入5,重复元素,不会插入
//删除键值为6的元素
int>::reverse_iterator rit; //定义反向迭代器
//反向遍历集合中的所有元素
for(rit = s.rbegin(); rit != s.rend(); rit++)
{
" ";
}
cout << endl;
int>::iterator it;

it = s.begin();
for(int i = 0; i < 2; i++)
it = s.erase(it);
for(it = s.begin(); it != s.end(); it++)
" ";
cout << endl;

s.clear();
cout << s.size() << endl;

return 0;
}
/*
运行结果:
5 3 1
5
0
*/


5.元素的检索


#include<iostream>  
#include<set>
using namespace std;
int main()
{
int> s;
//第一次插入5,可以插入
s.insert(1);
s.insert(6);
s.insert(3);
//第二次插入5,重复元素,不会插入
int>::iterator it;
//查找键值为6的元素
if(it != s.end())
cout << *it << endl;
else
"not find it" << endl;
it = s.find(20);
if(it != s.end())
cout << *it << endl;
else
"not find it" << endl;
return 0;
}
/*
运行结果:
6
not find it
*/



下面这种方法也能判断一个数是否在集合中:

#include <cstdio>  
#include <set>
using namespace std;
int main() {
int> s;
int a;
for(int i = 0; i < 10; i++)
s.insert(i);
for(int i = 0; i < 5; i++) {
"%d", &a);
if(!s.count(a)) //不存在
"does not exist\n");
else
"exist\n");
}
return 0;
}



6.自定义比较函数

         使用insert将元素插入到集合中去的时候,集合会根据设定的比较函数奖该元素放到该放的节点上去。在定义集合的时候,如果没有指定比较函数,那么采用默认的比较函数,即按键值从小到大的顺序插入元素。但在很多情况下,需要自己编写比较函数。

编写比较函数有两种方法。

(1)如果元素不是结构体,那么可以编写比较函数。下面的程序比较规则为按键值从大到小的顺序插入到集合中。



#include<iostream>  
#include<set>
using namespace std;
struct mycomp
{ //自定义比较函数,重载“()”操作符
bool operator() (const int &a, const int &b)
{
if(a != b)
return a > b;
else
return a > b;
}
};
int main()
{
int, mycomp> s; //采用比较函数mycomp
//第一次插入5,可以插入
s.insert(1);
s.insert(6);
s.insert(3);
//第二次插入5,重复元素,不会插入
int,mycomp>::iterator it;
for(it = s.begin(); it != s.end(); it++)
" ";
cout << endl;
return 0;
}
/*
运行结果:6 5 3 1
*/

(2)如果元素是结构体,那么可以直接把比较函数写在结构体内。


#include<iostream>  
#include<set>
#include<string>
using namespace std;
struct Info
{
string name;
double score;
bool operator < (const Info &a) const // 重载“<”操作符,自定义排序规则
{
//按score由大到小排序。如果要由小到大排序,使用“>”即可。
return a.score < score;
}
};
int main()
{
set<Info> s;
Info info;

//插入三个元素
"Jack";
info.score = 80;
s.insert(info);
"Tom";
info.score = 99;
s.insert(info);
"Steaven";
info.score = 60;
s.insert(info);

set<Info>::iterator it;
for(it = s.begin(); it != s.end(); it++)
" : " << (*it).score << endl;
return 0;
}
/*
运行结果:
Tom : 99
Jack : 80
Steaven : 60
*/




Set常用函数:跟其他容器的函数差不多,好像都通用

c++ stl容器set成员函数:begin()--返回指向第一个元素的迭代器

c++ stl容器set成员函数:clear()--清除所有元素

c++ stl容器set成员函数:count()--返回某个值元素的个数

c++ stl容器set成员函数:empty()--如果集合为空,返回true

c++ stl容器set成员函数:end()--返回指向最后一个元素的迭代器

c++ stl容器set成员函数:equal_range()--返回集合中与给定值相等的上下限的两个迭代器

c++ stl容器set成员函数:erase()--删除集合中的元素

c++ stl容器set成员函数:find()--返回一个指向被查找到元素的迭代器

c++ stl容器set成员函数:get_allocator()--返回集合的分配器

c++ stl容器set成员函数:insert()--在集合中插入元素

c++ stl容器set成员函数:lower_bound()--返回指向大于(或等于)某值的第一个元素的迭代器

c++ stl容器set成员函数:key_comp()--返回一个用于元素间值比较的函数

c++ stl容器set成员函数:max_size()--返回集合能容纳的元素的最大限值

c++ stl容器set成员函数:rbegin()--返回指向集合中最后一个元素的反向迭代器

c++ stl容器set成员函数:rend()--返回指向集合中第一个元素的反向迭代器

c++ stl容器set成员函数:size()--集合中元素的数目

c++ stl容器set成员函数:swap()--交换两个集合变量

c++ stl容器set成员函数:upper_bound()--返回大于某个值元素的迭代器

c++ stl容器set成员函数:value_comp()--返回一个用于比较元素间的值的函数

集合


使用set或multiset之前,必须加入头文件<set>


Set、multiset都是集合类,差别在与set中不允许有重复元素,multiset中允许有重复元素。


STL-set_#include

sets和multiset内部以平衡二叉树实现


STL-set_成员函数_02


1.   常用函数

1)        构造函数和析构函数

set c:创建空集合,不包含任何元素

set c(op):以op为排序准则,产生一个空的set

set c1(c2):复制c2中的元素到c1中

set c(const value_type *first, const value_type* last):复制[first, last)之间元素构成新集合

set c(const value_type *first, const value_type* last,op):以op为排序准则,复制[first, last)之间元素构成新集合。

c.~set()销毁所有元素,释放内存


multiset mc:创建空集合,不包含任何元素

multiset mc(op):以op为排序准则,产生一个空的set

multiset c1(c2):复制c2中的元素到c1中

multiset c(const value_type *first, const value_type* last):复制[first, last)之间元素构成新集合

multiset c(const value_type *first, const value_type* last,op):以op为排序准则,复制[first, last)之间元素构成新集合。

c.~set()销毁所有元素,释放内存


// constructing sets  
#include <iostream>
#include <set>

bool fncomp (int lhs, int rhs) {return lhs<rhs;}

struct classcomp {
bool operator() (const int& lhs, const int& rhs) const
return lhs<rhs;}
};

int main ()
{
int> first; // empty set of ints

int myints[]= {10,20,30,40,50};
int> second (myints,myints+5); // range

int> third (second); // a copy of second

int> fourth (second.begin(), second.end()); // iterator ctor.

int,classcomp> fifth; // class as Compare

bool(*fn_pt)(int,int) = fncomp;
int,bool(*)(int,int)> sixth (fn_pt); // function pointer as Compare

return 0;
}





2)        大小、判断空函数

  int size() const:返回容器元素个数
    bool empty() const:判断容器是否为空,若返回true,表明容器已空

3)        增加、删除函数

 pair<iterator,bool> insert( x):插入元素x

    iterator insert(iterator it,x):在迭代器it处插入元素x

    void insert(const value_type *first,const value_type *last):插入[first, last)之间元素

    iterator erase(iterator it):删除迭代器指针it处元素

    iterator erase(iterator first,iterator last):删除[first, last)之间元素

    size_type erase(const Key& key):删除元素值等于key的元素


#include <iostream>  
#include <set>

int main ()
{
int> myset;
int>::iterator it;
int>::iterator,bool> ret;

// set some initial values:
for (int i=1; i<=5; ++i) myset.insert(i*10); // set: 10 20 30 40 50

// no new element inserted

if (ret.second==false) it=ret.first; // "it" now points to element 20

// max efficiency inserting
// max efficiency inserting
// no max efficiency inserting

int myints[]= {5,10,15}; // 10 already in set, not inserted
myset.insert (myints,myints+3);

"myset contains:";
for (it=myset.begin(); it!=myset.end(); ++it)
' ' << *it;
'\n';

return 0;
}



#include <iostream>  
#include <set>

int main ()
{
int> myset;
int>::iterator it;

// insert some values:
for (int i=1; i<10; i++) myset.insert(i*10); // 10 20 30 40 50 60 70 80 90

it = myset.begin();
// "it" points now to 20

myset.erase (it);

myset.erase (40);

it = myset.find (60);
myset.erase (it, myset.end());

"myset contains:";
for (it=myset.begin(); it!=myset.end(); ++it)
' ' << *it;
'\n';

return 0;
}



4)        遍历函数

 iterator begin():返回首元素的迭代器指针

    iterator end():返回尾元素的迭代器指针
    reverse_iterator rbegin():返回尾元素的逆向迭代器指针
    reverse_iterator rend():返回首元素前一个位置的迭代器指针

     

#include <iostream>  
#include <set>

int main ()
{
int myints[] = {75,23,65,42,13};
int> myset (myints,myints+5);

"myset contains:";
for (std::set<int>::iterator it=myset.begin(); it!=myset.end(); ++it)
' ' << *it;

'\n';

return 0;
}



5)        操作函数

const_iterator lower_bound(const Key& key):返回容器中大于等于key的迭代器指针

    const_iterator upper_bound(const Key& key):返回容器中大于key的迭代器指针

    int count(const Key& key) const:返回容器中元素等于key的元素的个数
    pair<const_iterator,const_iterator> equal_range(const Key& key) const:返回容器中元素值等于key的迭代指针[first, last)
    const_iterator find(const Key& key) const:查找功能,返回元素值等于key的迭代器指针
    void swap(set& s):交换集合元素
    void swap(multiset& s):交换多集合元素  


#include <iostream>  
#include <set>

int main ()
{
int> myset;
int>::iterator itlow,itup;

for (int i=1; i<10; i++) myset.insert(i*10); // 10 20 30 40 50 60 70 80 90

// ^
// ^

// 10 20 70 80 90

"myset contains:";
for (std::set<int>::iterator it=myset.begin(); it!=myset.end(); ++it)
' ' << *it;
'\n';

return 0;
}


#include "stdafx.h"  
#include <iostream>
#include <set>

using namespace std;

int main ()
{
int> myset;

for (int i=1; i<=5; i++) myset.insert(i*10); // myset: 10 20 30 40 50

int>::const_iterator,set<int>::const_iterator> ret;
ret = myset.equal_range(30);

"the lower bound points to: " << *ret.first << '\n';
"the upper bound points to: " << *ret.second << '\n';

return 0;
}




#include "stdafx.h"  
#include <iostream>
#include <set>

using namespace std;

int main ()
{
int myints[]={12,75,10,32,20,25};
int> first (myints,myints+3); // 10,12,75
int> second (myints+3,myints+6); // 20,25,32

first.swap(second);

"first contains:";
for (set<int>::iterator it=first.begin(); it!=first.end(); ++it)
' ' << *it;
'\n';

"second contains:";
for (set<int>::iterator it=second.begin(); it!=second.end(); ++it)
' ' << *it;
'\n';

return 0;
}



1.创建set集合对象



​​ 

#include<iostream>
#include<set>
using namespace std;
int main()
{
int> s;
return 0;
}

2.元素的插入与中序遍历


        采用inset()方法把元素插入到集合中,插入规则在默认的比较规则下,是按元素值从小到大插入,如果自己指定了比较规则函数,则按自定义比较规则函数插入。使用前向迭代器对集合中序遍历,结果正好是元素排序后的结果。


#include<iostream>  
#include<set>
using namespace std;
int main()
{
int> s;
//第一次插入5,可以插入
s.insert(1);
s.insert(6);
s.insert(3);
//第二次插入5,重复元素,不会插入
int>::iterator it; //定义前向迭代器
//中序遍历集合中的所有元素
for(it = s.begin(); it != s.end(); it++)
{
" ";
}
cout << endl;
return 0;
}
//运行结果:1 3 5 6

3.元素的方向遍历

#include<iostream>  
#include<set>
using namespace std;
int main()
{
int> s;
//第一次插入5,可以插入
s.insert(1);
s.insert(6);
s.insert(3);
//第二次插入5,重复元素,不会插入
int>::reverse_iterator rit; //定义反向迭代器
//反向遍历集合中的所有元素
for(rit = s.rbegin(); rit != s.rend(); rit++)
{
" ";
}
cout << endl;
return 0;
}
//运行结果:6 5 3 1


4.元素的删除


#include<iostream>  
#include<set>
using namespace std;
int main()
{
int> s;
//第一次插入5,可以插入
s.insert(1);
s.insert(6);
s.insert(3);
//第二次插入5,重复元素,不会插入
//删除键值为6的元素
int>::reverse_iterator rit; //定义反向迭代器
//反向遍历集合中的所有元素
for(rit = s.rbegin(); rit != s.rend(); rit++)
{
" ";
}
cout << endl;
int>::iterator it;

it = s.begin();
for(int i = 0; i < 2; i++)
it = s.erase(it);
for(it = s.begin(); it != s.end(); it++)
" ";
cout << endl;

s.clear();
cout << s.size() << endl;

return 0;
}
/*
运行结果:
5 3 1
5
0
*/


5.元素的检索


#include<iostream>  
#include<set>
using namespace std;
int main()
{
int> s;
//第一次插入5,可以插入
s.insert(1);
s.insert(6);
s.insert(3);
//第二次插入5,重复元素,不会插入
int>::iterator it;
//查找键值为6的元素
if(it != s.end())
cout << *it << endl;
else
"not find it" << endl;
it = s.find(20);
if(it != s.end())
cout << *it << endl;
else
"not find it" << endl;
return 0;
}
/*
运行结果:
6
not find it
*/



下面这种方法也能判断一个数是否在集合中:


#include <cstdio>  
#include <set>
using namespace std;
int main() {
int> s;
int a;
for(int i = 0; i < 10; i++)
s.insert(i);
for(int i = 0; i < 5; i++) {
"%d", &a);
if(!s.count(a)) //不存在
"does not exist\n");
else
"exist\n");
}
return 0;
}



6.自定义比较函数

         使用insert将元素插入到集合中去的时候,集合会根据设定的比较函数奖该元素放到该放的节点上去。在定义集合的时候,如果没有指定比较函数,那么采用默认的比较函数,即按键值从小到大的顺序插入元素。但在很多情况下,需要自己编写比较函数。

编写比较函数有两种方法。

(1)如果元素不是结构体,那么可以编写比较函数。下面的程序比较规则为按键值从大到小的顺序插入到集合中。


#include<iostream>  
#include<set>
using namespace std;
struct mycomp
{ //自定义比较函数,重载“()”操作符
bool operator() (const int &a, const int &b)
{
if(a != b)
return a > b;
else
return a > b;
}
};
int main()
{
int, mycomp> s; //采用比较函数mycomp
//第一次插入5,可以插入
s.insert(1);
s.insert(6);
s.insert(3);
//第二次插入5,重复元素,不会插入
int,mycomp>::iterator it;
for(it = s.begin(); it != s.end(); it++)
" ";
cout << endl;
return 0;
}
/*
运行结果:6 5 3 1
*/

(2)如果元素是结构体,那么可以直接把比较函数写在结构体内。

#include<iostream>  
#include<set>
#include<string>
using namespace std;
struct Info
{
string name;
double score;
bool operator < (const Info &a) const // 重载“<”操作符,自定义排序规则
{
//按score由大到小排序。如果要由小到大排序,使用“>”即可。
return a.score < score;
}
};
int main()
{
set<Info> s;
Info info;

//插入三个元素
"Jack";
info.score = 80;
s.insert(info);
"Tom";
info.score = 99;
s.insert(info);
"Steaven";
info.score = 60;
s.insert(info);

set<Info>::iterator it;
for(it = s.begin(); it != s.end(); it++)
" : " << (*it).score << endl;
return 0;
}
/*
运行结果:
Tom : 99
Jack : 80
Steaven : 60
*/