C++ set 函数的使用

________________________________________________________________________________________________________________

1.关于set

C++ STL 之所以得到广泛的赞誉,STL封装了许多复杂的数据结构算法和大量常用数据结构操作。vector封装数组list封装了链表map和set封装了二叉树

关于 set是STL中一种标准关联容器。它底层使用平衡的搜索树——红黑树实现,也称RB树(Red-Black Tree)。插入删除操作时仅仅需要指针操作节点即可完成,不涉及到内存移动和拷贝,所以效率比较高。


set 的特点:

1.set中每个元素的值都唯一,即 无重复元素
2.set能根据元素的值默认从小到大 排序 (可以通过自定义函数更改排序方式)

如果需要集合中的元素允许重复那么可以使用multiset。

2.set 容器的创建


#include <iostream>
#include <set>
#include <functional>
using namespace std;
set<int> s;
 
int main(){
   set<int > seta; //默认是小于比较器less<int>(即默认 从小到大排序)的set

   set<int, greater<int> > setb; //创建一个(从大到小排序)的set,需包含头文件functional                          
 
   int a[5] = {1,2,3,4,5};
   set<int > setc(a,a+5); //数组a初始化一个set;
 
   set<int > setd(setc.begin(),setc.end()); //setc初始化一个set
   //上述两例均为区间初始化
 
   set<int > sete(setd); //拷贝构造创建set
   return 0;
}


3. set 的常用函数

________________________________________________________________________________________________________________

使用时注意包含头文件<set>  
 
s.begin()      返回一个迭代器,返回的值为set容器的第一个元素
 
s.end()      返回一个迭代器,返回的值为set容器的最后一个元素
 
s.clear()       删除set容器中的所有的元素
 
s.empty()     判断set容器是否为空
 
s.insert()      插入一个元素
 
s.erase()       删除一个元素
 
s.size()     返回当前set容器中的元素个数

s.count()       用来查找set中某个某个键值出现的次数。
                因为一个键值在set只可能出现01次,
                可以用来判断某一键值是否在set出现过了(
                可以用来判断输入的数据是否重复读入)
                
s.find()        返回给定值的定位器,如果没找到则返回end() 


3.1 insert 插入

  1. pair<iterator,bool> insert(const value_type& __x);
    //直接插入元素
  2. iterator insert(iterator __position, const value_type& __x);
    // 从定位器某位置插入
  3. void insert(_InputIterator __first, _InputIterator __last)
    //将一段区间 插入
#include <iostream>
#include <set>
#include <bits/stdc++.h>
using namespace std;
int cnt=0;
int main(){

    set<int > s1;
    set<int > s2;

    //pair<iterator,bool> insert(const value_type& __x);
    s1.insert(10);
	s1.insert(10);
	s1.insert(12);
	s1.insert(13);
	s1.insert(9);

     cout << "Test output :" << ++cnt << ":" << endl;
     set<int>::iterator it;
	for(it = s1.begin(); it!=s1.end(); it++){
		cout<<*it<<" ";
	}
	cout<<endl;

//--------------------------------------------------------------------------------------------------------------------------------------------
   //iterator insert(iterator __position, const value_type& __x);
    cout << "Test output :" << ++cnt << ":" << endl;
	s1.insert(s1.begin(), 2);
	for(it = s1.begin(); it!=s1.end(); it++){ //自动排序元素
		cout<<*it<<" ";
	}
	cout<<endl;



//-------------------------------------------------------------------------------------------------------------------------------------------
	//template<class _InputIterator>
	//void insert(_InputIterator __first, _InputIterator __last)

    int  a[4] = {3,12,13,14};
    s1.insert(a,a+4); //将区间[a, a+4]里的元素插入容器

    cout << "Test output :" << ++cnt << ":" << endl;
	for(it = s1.begin(); it!=s1.end(); it++){ //自动排序元素
		cout<<*it<<" ";
	}
	cout<<endl;

  
  
    s2.insert(1);
    s2.insert(s1.begin(), s1.end());
    
    cout << "Test output :" << ++cnt << ":" << endl;
	for(it = s2.begin(); it!=s2.end(); it++){ //自动排序元素
		cout<<*it<<" ";
	}
	cout<<endl;
  
     return 0;
}

/*   结果:
Test output :1:
9 10 12 13
Test output :2:
2 9 10 12 13
Test output :3:
2 3 9 10 12 13 14
Test output :4:
1 2 3 9 10 12 13 14
*/


3.2 erase 删除

  1. erase(iterator) , 删除定位器iterator指向的值
  2. erase(first,second), 删除定位器first和second之间的值 ,左闭右开[ l, r)
  3. erase(key_value) , 删除键值key_value的值
#include <iostream>
#include <set>
using namespace std;

int main()
{
	set<int> s;
	set<int>::iterator it;
	
	for(int i = 1 ; i <= 10 ; i++)
	{
		s.insert(i);
		cout << i << "  " ;
	}
     cout << endl;

//------------------------------------------------------------------------------------------------------------------------------------------
   //  erase(iterator)       删除定位器iterator指向的值
	it = s.begin();	      // 删除第一个值

	s.erase(s.begin());

	cout << "第一个值删除之后 :"  << endl;

	for(it = s.begin() ; it != s.end() ; ++it)
	{
		cout<<*it<<" ";
	}
	cout << endl;


//-------------------------------------------------------------------------------------------------------------------------------------------
	//erase(first,second), 删除定位器first和second之间的值,左闭右开[ l, r)
	s.erase(++s.begin(),--s.end());
	
	cout << "第二种删除 从第二个到 倒数第二个区间中的元素 之后 :"  << endl;

	for(it= s.begin() ; it != s.end() ; it++)
	{
		cout<<*it<<" ";
	}
	cout << endl;


 //-----------------------------------------------------------------------------------------------------------------------------------------
	s.erase(10);
	cout << "第三次删除的是: 10" << endl;
	for(it = s.begin() ; it != s.end() ; it++)
	{
       cout<<*it<<" ";
	}
	cout << endl;

	return 0;

}
/* 结果是: 

1  2  3  4  5  6  7  8  9  10
第一个值删除之后 :
2 3 4 5 6 7 8 9 10
第二种删除 从第二个到 倒数第二个区间中的元素 之后 :
2 10
第三次删除的是: 8
2
*/

3.3 find() 函数的使用

find() ,返回给定值的定位器,如果容器中不存在该元素,返回值等于end()

end()返回指向最后一个元素的下一个地址,存放的是当前容器的大小

#include <iostream>
#include <set>

using namespace std;

int main()
{
	set<int> s;
	set<int>::iterator it;

	for(int i = 1 ; i <= 10 ; i++)
	{
		s.insert(i);
		cout << i << "  " ;
	}
     cout << endl;

    it=s.find(2);    cout<<*it<<endl;

    it=s.find(11);   cout<<*it<<endl;

    it=s.end();      cout<<*it<<endl;
    
	return 0;
}

/*  结果为:
1  2  3  4  5  6  7  8  9  10
2
10
10
*/



3.4 lower_bound 和upper_bound

注意 * 号 的使用
lower_bound(key_value) ,返回第一个大于等于key_value的定位器
upper_bound(key_value),返回最后一个大于key_value的定位器

#include <iostream>
#include <set>

using namespace std;

int main()
{
	set<int> s;
	set<int>::iterator it;

	for(int i = 1 ; i <= 10 ; i++)
	{
		s.insert(i);
		cout << i << "  " ;
	}
     cout << endl;

    cout << "lower_bound & upper_bound test:" << endl;

   cout << "第一个大于或等于3的元素: " << *s.lower_bound(3) << endl;
   cout << "第一个大于3的元素: " <<*s.upper_bound(3) << endl;

   cout<<"\n"<<endl;
   
   cout << "第一个大于或等于6的元素: " << *s.lower_bound(6) << endl;
   cout << "第一个大于6的元素: " <<*s.upper_bound(6) << endl;

    return 0;
}
/* 结果为:
1  2  3  4  5  6  7  8  9  10
lower_bound & upper_bound test:
第一个大于或等于3的元素: 3
第一个大于3的元素: 4


第一个大于或等于6的元素: 6
第一个大于6的元素: 7

*/

3.5 count() 的 使用

计算容器中某个元素的 出现次数
由于set容器的无重复元素的特性 返回值只有 0 或1

#include <iostream>
#include <set>

using namespace std;

int main()
{
	set<int> s;
  
    if(!s.count(1))
    {
         s.insert(1);
    }
    else
    {
    cout<< "1 在容器中 "<<endl;

    }

    if(s.count(1))
    {
        cout<< "1 在容器中 "<<endl;
    }

	return 0;
}

/*    结果为:
1 在容器中
*/

4. 自定义比较函数


  (1)元素不是结构体:

    例:

  //自定义比较函数myComp,重载“()”操作符

struct myComp
{
   
   bool operator()(const your_type &a,const your_type &b)
	{
		return a.data > b.data;
	}
};

set<int,myComp>s;

set<int,myComp>::iterator it;

 

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

        例:

struct Info
{
	string name;
	float score;
	
	//重载“<”操作符,自定义排序规则

	bool operator < (const Info &a) const
    {
		//按score从大到小排列
		return a.score<score;
	}
};


set<Info> s;

set<Info>::iterator it;

5. set 拓展使用

set 与 pair<int ,int > 的结合, 或与 stu 结构体 都实现了
(x,y)的二元组 优先 按x 从小到大排序, x相同时, 按y 从小到大排序

但在 set< pair<int,int > >s; 排序 为默认顺序
set< Stu > s1; 排序 为 结构体中自己 构造的排序

#include <iostream>
#include <bits/stdc++.h>

using namespace std;

struct Stu
{
    int x;
    int y;

    //重载“<”操作符,自定义排序规则
    bool operator < (const Stu  &a) const
    {
        //按y从大到小排列
        if(a.x!=x)
            return x<a.x;
        else
            return y<a.y;
    }
};



int main()
{
    set< pair<int,int > >s;

    s.insert({10,10});
    s.insert({8,20});
    s.insert({20,6});
    s.insert({8,6});


    set< pair<int,int > > :: iterator it ;
    for(it=s.begin(); it!=s.end(); it++)
    {
        cout<<it->first <<" "<<it->second<<endl;
    }
    cout<<"\n\n";

//----------------------------------------------------------------------

    set< Stu  > s1;

    s1.insert({10,10});
    s1.insert({8,20});
    s1.insert({20,6});
    s1.insert({8,6});


    set< Stu > :: iterator it1;
    for(it1=s1.begin(); it1!=s1.end(); it1++)
    {
        cout<<it1->x<<" "<<it1->y<<endl;
    }

    return 0;
}

8 6
8 20
10 10
20 6


8 6
8 20
10 10
20 6

猜你喜欢

转载自blog.csdn.net/nefu__lian/article/details/107929144