算术仿函数 template<class T> T plus<T> //加法仿函数 template<class T> T minus<T> //减法仿函数 template<class T> T multiplies<T> //乘法仿函数 template<class T> T divides<T> //除法仿函数 template<class T> T modulus<T> //取模仿函数 template<class T> T negate<T> //取反仿函数 一元谓词 关系仿函数 template<class T> bool equal_to<T> //等于 template<class T> bool not_equal_to<T> //不等于 template<class T> bool greater<T> //大于 template<class T> bool greater_equal<T> //大于等于 template<class T> bool less<T> //小于 template<class T> bool less_equal<T> //小于等于 逻辑仿函数 template<class T> bool logical_and<T> //逻辑与 template<class T> bool logical_or<T> //逻辑或 template<class T> bool logical_not<T> //逻辑非
函数对象 重载函数调用操作符 () 的 类,其对象常称为函数对象
函数对象可以有自己的状态 函数对象可以作为参数传递 一个参数的函数对象叫做一元仿函数 两个参数的函数对象叫做二元仿函数 什么是谓词 返回 bool 类型的仿函数称为谓词
一元谓词 如果 operator() 接受一个参数,那么叫做一元谓词
比如 find_if 算法
二元谓词 如果 operator() 接受两个参数,那么叫做二元谓词
比如 sort 算法
特点 所有元素都会根据元素的键值自动排序 默认排序规则是从小到大,可以通过仿函数指定排序规则 map / multimap 属于关联式容器,底层结构是用红黑树实现 不可以修改键值,可以通过删除再插入的方式实现 可以根据 key 值快速找到 value 值 可以通过下标 [] 的方式快速查找、插入和更新对应的 value 案例 公司今天招聘了10个员工(ABCDEFGHIJ),10 名员工进入公司之后,需要指派员工在哪个部门工作 员工信息有: 姓名 工资组成;部门分为:策划、美术、研发 随机给 10 名员工分配部门和工资 通过 multimap 进行信息的插入 key(部门编号) value(员工) 分部门显示员工信息 思路:
创建 10 名员工,放到 vector 中 遍历 vector 容器,取出每个员工,进行随机分组 分组后,将员工部门编号作为 key,具体员工作为 value,放入到 multimap 容器中 分部门显示员工信息 class Worker{ public: Worker(string name, int salary){ m_name = name; m_salary = salary; } void printWorker(){ cout << "姓名:" << m_name << " 工资:" << m_salary << endl; } private: string m_name; int m_salary; }; void createWorkers(vector<Worker> &v){ string nameSeed = "ABCDEFGHIJ"; for(int i = 0; i < nameSeed....
关联式容器 底层结构使用红黑树实现(二叉树->二叉搜索树->平衡二叉树->红黑树) 自动排序 不可以修改值,可以通过删除再插入的方式实现 自定义数据类型:
class Person{ public: Person(string name, int age, int height){ this->m_name = name; this->m_age = age; this->m_height = height; } bool operator<(const Person &p2) const{ // 注意:函数和形参都要添加 const 修饰符 if(this->m_age == p2.m_age){ return this->m_height > p2.m_height; } return this->m_age < p2.m_age; } void printPerson()const{ cout << "姓名:" << this->m_name << " 年龄:" << this->m_age << " 身高:" << this->m_height << endl; } private: string m_name; int m_age; int m_height; }; int main() { set<Person> lp; lp....
注意事项 双向循环链表 不支持随机访问 因为不支持随机访问,所以也不能用全局的排序算法 sort 一般不支持随机访问的容器会自己提供 sort 方法 自定义类型要指定排序规则 排序案例 案例描述:将 Person 自定义数据类型进行排序,Person 中属性有姓名、年龄、身高
排序规则:按照年龄进行升序,如果年龄相同按照身高进行降序
class Person{ public: Person(string name, int age, int height){ this->m_name = name; this->m_age = age; this->m_height = height; } bool operator<(const Person &p2){ if(this->m_age == p2.m_age){ return this->m_height > p2.m_height; } return this->m_age < p2.m_age; } void printPerson()const{ cout << "姓名:" << this->m_name << " 年龄:" << this->m_age << " 身高:" << this->m_height << endl; } private: string m_name; int m_age; int m_height; }; int main() { list<Person> lp; lp....