c++:STL(set)

既上篇,这篇继续讲述set。

set:

(1)set是一个集合容器,其中所包含的元素是唯一的,集合中的元素按一定的顺序排列。元素插入过程是按排序规则插入,所          以不能指定插入位置

(2)set采用红黑树变体的数据结构实现,红黑树属于平衡二叉树。在插入操作和删除操作上比vector快

(3)set不可以直接存取元素。(不可以使用at.(pos)与[]操作符)。

(4)multiset与set的区别:set支持唯一键值,每个元素值只能出现一次;而multiset中同一值可以出现多次。

(5)不可以直接修改set或multiset容器中的元素值,因为该类容器是自动排序的。如果希望修改一个元素值,必须先删除原有            的元素,再插入新的元素

(6)set 默认构造对象:

         如:set<int> setInt;            //一个存放int的set容器。

(7)set的相关用法

set.insert(elem);                          //在容器中插入元素。
set.begin();                                  //返回容器中第一个数据的迭代器。
set.end();                                     //返回容器中最后一个数据之后的迭代器。
set.rbegin();                                //返回容器中倒数第一个元素的迭代器。
set.rend();                                   //返回容器中倒数最后一个元素的后面的迭代器。

set<int,less<int> >  setIntA;                    //该容器是按升序方式排列元素。
set<int,greater<int>> setIntB;                //该容器是按降序方式排列元素。

set(const set &st);                                    //拷贝构造函数
set& operator=(const set &st);               //重载等号操作符
set.swap(st);                                            //交换两个集合容器

set.size();                                          //返回容器中元素的数目
set.empty();                                      //判断容器是否为空

set.clear();                                        //清除所有元素
set.erase(pos);                                //删除pos迭代器所指的元素,返回下一个元素的迭代器。
set.erase(beg,end);                        //删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
set.erase(elem);                             //删除容器中值为elem的元素。

set.find(elem);                              //查找elem元素,返回指向elem元素的迭代器。
set.count(elem);             //返回容器中值为elem的元素个数。对set来说,要么是0,要么是1。对multiset来说,值可能大于1。
set.lower_bound(elem);             //返回第一个>=elem元素的迭代器。
set.upper_bound(elem);            //返回第一个>elem元素的迭代器。
set.equal_range(elem);         //返回容器中与elem相等的上下限的两个迭代器。上限是闭区间,下限是开区间,如[beg,end)。

(8)set<int>相当于 set<int,less<int>>。
         less<int>与greater<int>中的int可以改成其它类型,该类型主要要跟set容纳的数据类型一致。

疑问1:less<>与greater<>是什么?
疑问2:如果set<>不包含int类型,而是包含自定义类型,set容器如何排序?

要解决如上两个问题,需要了解容器的函数对象,也叫伪函数,英文名叫functor。
下面将讲解什么是functor,functor的用法:

解答:尽管函数指针被广泛用于实现函数回调,但C++还提供了一个重要的实现回调函数的方法,那就是函数对象。
           functor,翻译成函数对象,伪函数,算符,是重载了“()”操作符的普通类对象。从语法上讲,它与普通函数行为类似。
           greater<>与less<>就是函数对象。


9)pair:

1、pair译为对组,可以将两个值视为一个单元。

2、pair<T1,T2>存放的两个值的类型,可以不一样,如T1为int,T2为float。T1,T2也可以是自定义类型。

3、pair.first是pair里面的第一个值,是T1类型。

4、pair.second是pair里面的第二个值,是T2类型。

举例:注意注释

#include<set>
#include<iostream>
#include<cstring>
using namespace std;

class Student
{
	friend class Cmp;
private:
	char m_name[20];
	int m_age;
public:
	Student(char *n,int a);
	void print() const;
	bool operator > (const Student &s) const;
	bool operator < (const Student &s) const;
};

Student::Student(char *n,int a)          //有参构造函数
{
	strcpy(m_name , n);
	m_age = a;
}

void Student::print() const              //输出信息
{
	cout<< m_name  << " " << m_age <<endl;
}

bool Student::operator > (const Student &s) const     
{
	//return (this->m_age > s.m_age);                //利用年龄来比较大小
	return (strcmp(this->m_name , s.m_name)> 0);     //利用名字来比较大小
} 

bool Student::operator < (const Student &s) const
{
	//return (this->m_age < s.m_age);                //利用年龄来比较大小
	return (strcmp(this->m_name , s.m_name)< 0);     //利用名字来比较大小
}

int main()
{
	//srand(time(NULL));   //随机抽样
    
    //less函数对象,默认是less,从大到小排序
	//priority_queue< Student , deque<Student> , less<Student> > q;  

    //greater函数对象,默认是greater,从小到大排序
	//priority_queue< int , deque<int> , greater<int> > q;  
	
    //Cmp函数对象,作用与greater相同
    //priority_queue< Student , deque<Student> , Cmp > q;    
	
    set<Student , less<Student> > s;
	
	Student s1("aa" ,24);
	Student s2("bb" ,19);
	//Student s6("bb" ,21);    //如果根据名字比较 s2把s6覆盖掉
	Student s3("cc" ,22);
	Student s4("dd" ,23);
	Student s5("ee" ,28);
	Student s6("ff" ,30);
	Student s7("gg" ,8);
	Student s8("mm" ,40);
	Student s9("zz" ,25);
	
	
	s.insert(s1);
	s.insert(s2);
	s.insert(s3);
	s.insert(s4);
	s.insert(s5);
	s.insert(s6);   
	s.insert(s7);
	s.insert(s8); 
	
	for(set<Student , less<Student> >::iterator it = s.begin(); it!=s.end(); it++)
	{
		it->print();                        //打印信息
	}
	
	cout<<  "size: " << s.size() <<endl;
	
	if(s.empty())                           //判断容器是否为空
	{
		cout<< "Set is empty!" <<endl;
	}
	else
	{
		cout<< "Set is not empty!" <<endl;
	}
	
	cout<< "--------------erase iterator---------------" <<endl;  //根据迭代器删除信息
	set<Student , less<Student> >::iterator it = s.begin();
	it++;
	s.erase(it);
	for(it = s.begin(); it!=s.end(); it++)
	{
		it->print();
	}
	
	cout<< "--------------erase element--------------" <<endl;    //根据元素删除信息
	Student ss("cc",22);
	s.erase(ss);
	for(it = s.begin(); it!=s.end(); it++)
	{
		it->print();
	}
	
	cout<< "--------------find--------------" <<endl;             //查找元素
	Student sss("zz",100);
	it = s.find(sss);
	if(it == s.end())
	{
		cout<< "not exist" <<endl;
	}
	else
	{
		it->print();
	}
	
	cout<< "--------------count--------------" <<endl;            //计数
	int num = s.count(sss);
	cout<< num <<endl;
	
	cout<< "--------------lower_bound--------------" <<endl;  //返回第一个>=元素的迭代器
	Student ssss("zz",100);
	it = s.lower_bound(ssss);
	if(it != s.end())
	{
		it->print();
	}
	else
	{
		cout<< "failure!" <<endl;
	}
	
	cout<< "--------------upper_bound--------------" <<endl;  //返回第一个>元素的迭代器
	Student xx("gg",0);
	it = s.upper_bound(xx);
	if(it != s.end())
	{
		it->print();
	}
	else
	{
		cout<< "failure!" <<endl;
	}
	
	return 0;
}


结果如下:

猜你喜欢

转载自blog.csdn.net/xutong98/article/details/81488961