大爱C++——set容器使用仿函数

来源:互联网 发布:电信网络电视节目 编辑:程序博客网 时间:2024/06/10 05:02

前面博客介绍过set容器了,这里还是简介一下set容器:

一:set容器简介

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

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

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

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

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

6.头文件为#include <set>


二:仿函数的简介  

函数对象functor的用法

尽管函数指针被广泛用于实现函数回调,但C++还提供了一个重要的实现回调函数的方法,那就是函数对象。

 functor,翻译成函数对象,伪函数,算符,是重载了“()”操作符的普通类对象。从语法上讲,它与普通函数行为类似。

greater<>less<>就是函数对象。

下面举出greater<int>的简易实现原理。

 

下面举出greater<int>的简易实现原理。

struct greater

{

bool operator() (const int& iLeft, const int& iRight)

{

       return (iLeft>iRight);    //如果是实现less<int>的话,这边是写return (iLeft<iRight);

}

}

容器就是调用函数对象的operator()方法去比较两个值的大小。

题目:学生包含学号,姓名属性,现要求任意插入几个学生对象到set容器中,使得容器中的学生按学号的升序排序。

 

解:

//学生类

class CStudent

{

public:

CStudent(int iID, string strName)

{

m_iID = iID;

m_strName = strName;

}

     int m_iID; //学号

     string m_strName; //姓名

}

//为保持主题鲜明,本类不写拷贝构造函数,不类也不需要写拷贝构造函数。但大家仍要有考虑拷贝构造函数的习惯。

 

//函数对象

struct StuFunctor

{

bool operator()  (const CStudent &stu1, const CStudent &stu2)

{

return (stu1.m_iID<stu2.m_iID);

}

}

 

//main函数

void main()

{

set<CStudent, StuFunctor> setStu;

setStu.insert(CStudent(3,"小张"));

setStu.insert(CStudent(1,"小李"));

setStu.insert(CStudent(5,"小王"));

setStu.insert(CStudent(2,"小刘"));

//此时容器setStu包含了四个学生对象,分别是按姓名顺序的“小李”,“小刘”,“小张”,“小王” 

}


三:问题抛出

有如下代码:
#include <iostream>using namespace std;#include "set"class Student{public:Student(char* name,int age){strcpy(this->name,name);this->age = age;}public:char name[64];int age;};//仿函数struct Function{bool operator()(const Student& left,const Student& right){if (left.age <right.age){return true;}else{return false;}}}; int main(){set<Student, Function> s;Student s1("小白",20);Student s2("小红", 19);Student s3("小黑", 19);s.insert(s1);s.insert(s2);s.insert(s3);for (set<Student, Function>::iterator it = s.begin(); it != s.end(); it++){cout << it->age << " " << it->name << endl;;}return 0;}



都知道set容器中的值是唯一的,代码中有个两个一样的年龄,那么我们怎判断是否插入成功与否?

这里我们要用到仿函数和pair。

四:pair简介

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

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

 pair.firstpair里面的第一个值,是T1类型。

 pair.secondpair里面的第二个值,是T2类型。

#include <iostream>using namespace std;#include "set"class Student{public:Student(char* name,int age){strcpy(this->name,name);this->age = age;}public:char name[64];int age;};//仿函数struct Function{bool operator()(const Student& left,const Student& right){if (left.age <right.age){return true;}else{return false;}}}; int main(){set<Student, Function> s;Student s1("小白",20);Student s2("小红", 19);Student s3("小黑", 19);pair<set<Student, Function>::iterator, bool> pair1 = s.insert(s1);if (pair1.second == true){cout << "插入成功" << endl;}else{cout << "插入失败" << endl;}pair<set<Student, Function>::iterator, bool> pair2= s.insert(s2);if (pair2.second == true){cout << "插入成功" << endl;}else{cout << "插入失败" << endl;}pair<set<Student, Function>::iterator, bool> pair3 = s.insert(s3);if (pair3.second == true){cout << "插入成功" << endl;}else{cout << "插入失败" << endl;}for (set<Student, Function>::iterator it = s.begin(); it != s.end(); it++){cout << it->age << " " << it->name << endl;;}return 0;}
这样就可以判读是否插入成功。



2 0