C++仿函数的介绍以及priority_queue的介绍和模拟实现

目录

1.仿函数

1.1仿函数的介绍

1.2自定义类型使用仿函数 

1.3自定义支持比较大小,但是比较的逻辑不是自己想要的逻辑

 2.优先级队列priority_queue

2.1priority_queue的介绍

2.2priority_queue的使用

2.3priority_queue的模拟实现 


1.仿函数

1.1仿函数的介绍

        仿函数的本质是一个类模板,只是这个类重载了operator(),所以当使用一个它的对象时看起来像使用和函数一样,所以被称为仿函数。

        下面通过仿函数的形式来写一个小于和大于的比较:

#include <iostream>
using namepsace std;template<class T>
class Less
{
public:bool operator()(const T& x, const T& y){return x < y;}
};template<class T>
class Greater
{
public:bool operator()(const T& x, const T& y){return x > y;}
};int main()
{Less<int> less_func;Greater<int> greater_fun;int a = 5;int b = 10;cout << less_func(a, b) << endl;cout << greater_fun(a, b) << endl;return 0;
}

1.2自定义类型使用仿函数 

        自定义类型需要使用仿函数进行比较时,需要在自定义类型里面提供<和>等比较运算符的重载。例如对日期类进行比较:

#include <iostream>
using namespace std;template<class T>
class Less
{
public:bool operator()(const T& x, const T& y){return x < y;}
};template<class T>
class Greater
{
public:bool operator()(const T& x, const T& y){return x > y;}
};class Date
{friend ostream& operator<<(ostream& _cout, const Date& d);
public:Date(int year = 1900, int month = 1, int day = 1): _year(year), _month(month), _day(day){}bool operator<(const Date& d)const{return (_year < d._year) ||(_year == d._year && _month < d._month) ||(_year == d._year && _month == d._month && _day < d._day);}bool operator>(const Date& d)const{return (_year > d._year) ||(_year == d._year && _month > d._month) ||(_year == d._year && _month == d._month && _day > d._day);}
private:int _year;int _month;int _day;
};int main()
{Less<Date> less_func;Greater<Date> greater_func;Date d1(2024, 9, 10);Date d2(2024, 8, 15);cout << less_func(d1, d2) << endl;cout << greater_func(d1, d2) << endl;return 0;
}

 1.3自定义支持比较大小,但是比较的逻辑不是自己想要的逻辑

         这个时候仿函数需要我们自己进行重新,比如想通过比较日期类的指针进行日期的比较时,就需要将仿函数写成下面这个样子:

#include <iostream>
using namespace std;class DateLess
{
public:bool operator()(Date* p1, Date* p2){return *p1 < *p2;}
};//日期类参考上一个代码中的日期类int main()
{Date d1(2024, 9, 10);Date d2(2024, 8, 15);Date* p1 = &d1;Date* p2 = &d2;DateLess func;cout << func(p1, p2) << endl;cout << func(p2, p1) << endl;return 0;
}

 2.优先级队列priority_queue

2.1priority_queue的介绍

        priority_queue的文档介绍

1.优先队列是一种容器适配器,根据严格的弱排序标准,它的第一个元素总是它所包含的元素中最大的。priority_queue包含在queue这个头文件中。

2.类似于堆,在堆中可以随时插入元素,并且只能检索最大堆元素(优先队列中位于顶部的元素)。在这里面(堆的介绍)中可以进行对堆的了解。

3.底层容器可以是任何标准容器类模板,也可以是其他特定设计的容器类。容器应该可以通过随机访问迭代器访问,并支持以下操作:

(1)empty():检测容器是否为空。

(2)size():返回容器中有效元素个数。

(3)front():返回容器中第一个元素的引用。

(4)push_back():在容器尾部插入元素。

(5)pop_back():删除容器尾部元素。

4.标准容器vector和deque满足这些需求。默认情况下,如果没有为特定的epriority_queue类实例化指定容器类,则使用vector。

5.需要支持随机访问迭代器,以便始终在内部保持堆结构。容器适配器通过在需要时自动调用算法函数make_heap(),push_heap()和pop_heap()来自动完成操作。

2.2priority_queue的使用

        优先级队列默认使用vector作为其底层存储数据的容器,在vector上又使用dui算法将vector中元素构造成堆的结构,因此priority_queue就是堆,所以需要用到堆的位置,都可以考虑使用priority_queue。注意:默认情况下priority_queue是大堆

#include <iostream>
#include <vector>
#include <queue>
#include <functional>
using namespace std;void test_priority_queue()
{// 默认情况下,创建的是大堆,其底层按照小于号比较vector<int> v{3, 2, 7, 6, 0, 4, 1, 9, 8, 5};priority_queue<int> q1;for (auto& e : v)q1.push(e);while(!q1.empty()){cout << q1.top() << " ";q1.pop();}
}int main()
{test_priority_queue();return 0;
}

        如果每次访问顶部元素时都访问的是最小元素,则需要建立小堆。使用的时候只需要把上述priority_queue<int> q1 改为 priority_queue<int, vector<int>, greater<int>>即可,默认大堆的情况下,给的仿函数是less<int>。

2.3priority_queue的模拟实现 

         优先级队列的存储结构就是一个堆,里面的向上调整算法(AdjustUp())和向下调整算法(AdjustDown())参考堆的结构和实现。

#pragma once
#include <vector>
template<class T>
class Less
{
public:bool operator()(const T& x, const T& y){return x < y;}
};template<class T>
class Greater
{
public:bool operator()(const T& x, const T& y){return x > y;}
};namespace XiaoC
{//默认是大堆,排升序,用小于符号template<class T, class Container = vector<T>, class Compare = Less<T>>class priority_queue{public:void AdjustUp(int child){Compare com;int parent = (child - 1) / 2;while (child > 0){//if (_con[parent] < _con[child])if (com(_con[parent], _con[child])){swap(_con[child], _con[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}}void push(const T& x){_con.push_back(x);AdjustUp(_con.size() - 1);}void AdjustDown(int parent){// 先假设左孩子小int child = parent * 2 + 1;Compare com;while (child < _con.size())  // child >= n说明孩子不存在,调整到叶子了{// 找出小的那个孩子//if (child + 1 < _con.size() && _con[child] < _con[child + 1])if (child + 1 < _con.size() && com(_con[child], _con[child + 1])){++child;}//if (_con[parent] < _con[child])if (com(_con[parent], _con[child])){swap(_con[child], _con[parent]);parent = child;child = parent * 2 + 1;}else{break;}}}void pop(){swap(_con[0], _con[_con.size() - 1]);_con.pop_back();AdjustDown(0);}const T& top() const{return _con[0];}size_t size() const{return _con.size();}bool empty() const{return _con.empty();}private:Container _con;};
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/54261.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C语言】指针篇 | 万字笔记

写在前面 在学习C语言过程&#xff0c;总有一个要点难点离不开&#xff0c;那就是大名鼎鼎的C语言指针&#xff0c;也是应为有指针的存在&#xff0c;使得C语言一直长盛不衰。因此不才把指针所学的所有功力都转换成这个笔记。希望对您有帮助&#x1f970;&#x1f970; 学习指…

彩虹易支付最新版源码及安装教程(修复BUG+新增加订单投诉功能)

该系统也没版本号&#xff0c;此版本目前是比较新的版本&#xff0c;增加了订单投诉功能&#xff0c;和一个好看的二次元模板。 此版本是全开源版&#xff0c;无一处加密文件,系统默认是安装后是打不开的&#xff0c; 本站特别修复了BUG文件&#xff0c;在PHP7.4环境下也没问…

Java的学习(语法相关)

字符串存储的问题 char 和字符串都是字符的集合&#xff0c;它们之间的确有相似性&#xff0c;但在 Java 中它们有着不同的存储机制和处理方式。让我从 char 和 String 的本质区别入手来解释。 1. char 和 String 的区别 char 是基本类型&#xff1a;char 是 Java 中的基本数据…

【C++】多态(下)

个人主页~ 多态&#xff08;上&#xff09;~ 多态 四、多态的原理1、虚表的存储位置2、多态的原理3、动态绑定和静态绑定 五、单继承和多继承关系的虚函数表1、单继承中的虚函数表2、多继承中的虚函数表 六、多态中的一些小tips 四、多态的原理 1、虚表的存储位置 class A {…

CORE MVC 过滤器 (筛选器)

MVC FrameWork MVCFramework MVC Core 过滤器 分 同步、异步 1、 授权筛选器 IAuthorizationFilter&#xff0c;IAsyncAuthorizationFilter 管道中运行的第一类筛选器&#xff0c;用来确定发出请求的用户是否有权限发出当前请求 2、资源筛选器 IResourceFilter &#xff0c;…

微软准备了 Windows 11 24H2 ISO “OOBE/BypassNRO“命令依然可用

Windows 11 24H2 可能在未来几周内开始推出。 微软已经要求 OEM 遵循新的指南准备好 Windows 11 24H2 就绪的驱动程序&#xff0c;并且现在已经开始准备媒体文件 (.ISO)。 OEM ISO 的链接已在微软服务器上发布。 一个标有"X23-81971_26100.1742.240906-0331.ge_release_sv…

Vue3项目开发——新闻发布管理系统(九)(完结篇)

文章目录 十一、用户信息管理1、用户基本资料管理1.1 页面设计1.2 封装接口,更新信息2、更换头像2.1 静态结构2.2 选择图片预览2.3 上传头像3、重置密码3.1 页面设计3.2 封装接口,更新密码十二、项目打包十三、系统全部源码下载十一、用户信息管理 用户信息管理包括功能:基…

第四届机器人、自动化与智能控制国际会议(ICRAIC 2024)征稿

第四届机器人、自动化与智能控制国际会议&#xff08;ICRAIC 2024&#xff09;由湖南第一师范学院主办&#xff0c;南京师范大学、山东女子学院、爱迩思出版社&#xff08;ELSP&#xff09;协办。 大会将专注于机器人、数字化、自动化、人工智能等技术的开发和融合&#xff0c…

如何让 Android 的前端页面像 iOS 一样“优雅”?

作者:方英杰&#xff08;崇之&#xff09; 最近在调研前端页面适配 Android 端异形屏的方案&#xff0c;调研过程中发现了一些比较有意思的点&#xff0c;本文主要是做一个总结。 一、提出问题 首先&#xff0c;我们需要知道 Android 上的前端适配面临着什么问题。 问题其实很…

【含文档】基于Springboot+Vue的停车场车位预约系统(含源码+数据库+lw)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 系统定…

ICPC-day1(NTT)

NTT经典例题 CCPC-Winter-Camp-day6-A——NTT经典例题 对于上面格式&#xff0c;如果想求出每个i的值可以使用卷积求出&#xff0c;因为阶乘j和阶乘i-j相乘的值为(i(i-j))i 补充一个二次剩余定理 P5491 【模板】二次剩余 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) //#in…

基于工业物联网的能源监控系统:边缘数据处理的应用

论文标题&#xff1a;《Industrial IoT-Based Energy Monitoring System: Using Data Processing at Edge》 作者信息&#xff1a; Akseer Ali MiraniAnshul AwasthiNiall O’MahonyJoseph Walsh 他们均来自爱尔兰的芒斯特技术大学IMaR研究中心&#xff0c;以及位于利默里克的…

JVM 基础、GC 算法与 JProfiler 监控工具详解

目录 1、引言 1.1 JVM内存与本地内存 1.2 JVM与JDK的关系 2、JVM基础 2.1 JVM&#xff08;Java Virtual Machine&#xff09; 2.2 Java与JVM的关系 2.3 JVM的内存结构 2.3.1 堆内存 2.3.2 栈内存 2.3.3 方法区 2.3.4 本地方法栈 2.3.5 程序计数器&#xff08;PC寄存…

【MySQL 07】内置函数

目录 1.日期函数 日期函数使用场景&#xff1a; 2.字符串函数 字符串函数使用场景&#xff1a; 3.数学函数 4.控制流函数 1.日期函数 函数示例&#xff1a; 1.在日期的基础上加日期 在该日期下&#xff0c;加上10天。 2.在日期的基础上减去时间 在该日期下减去2天 3.计算两…

Android Context是什么?有很多的context他们之间有什么区别?什么时候该使用哪个?

目录 一、Context是什么&#xff1f; 在Android中&#xff0c;Context是一个抽象类 &#xff0c;它代表了应用程序的当前状态&#xff0c;包括资源和类加载器等&#xff0c;它提供了一个应用运行所需的信息&#xff0c;比如我们要获取资源 &#xff0c;那么需要她&#xff0c;…

雷池 WAF 如何配置才能正确获取到源 IP

经常有大哥反馈说雷池攻击日志里显示的 IP 有问题。 这里我来讲一下为什么一些情况下雷池显示的攻击 IP 会有问题。 问题说明 默认情况下&#xff0c;雷池会通过 HTTP 连接的 Socket 套接字读取客户端 IP。在雷池作为最外层网管设备的时候这没有问题&#xff0c;雷池获取到的…

【寻找one piece的算法之路】——双指针算法!他与她是否会相遇呢?

&#x1f490;个人主页&#xff1a;初晴~ &#x1f4da;相关专栏&#xff1a;寻找one piece的刷题之路 什么是双指针算法 双指针算法是一种常用的编程技巧&#xff0c;尤其在处理数组和字符串问题时非常有效。这种方法的核心思想是使用两个指针来遍历数据结构&#xff0c;这两…

【HTML+CSS】仿电子美学打造响应式留言板

创建一个响应式的留言板 在这篇文章中&#xff0c;我们将学习如何创建一个简单而美观的留言板&#xff0c;它将包括基本的样式和动画效果&#xff0c;以及响应式设计&#xff0c;确保在不同设备上都能良好显示。 HTML 结构 首先&#xff0c;我们创建基本的HTML结构。留言板由…

Android SQLite的基本使用、生成Excel文件保存到本地

1. Android SQLite的基本使用 1.1. SQLiteOpenHelper Android 底层已经通过一个SQLiteOpenHelper的抽象类将数据库的创建&#xff0c;以及修改&#xff0c;更新等都放在了里面。 要使用它必须实现它的OnCreate(SQLiteDatabase db)&#xff0c;onUpgrade(SQLiteDatabase db, int…

YOLOv11改进 | 独家创新- 注意力篇 | YOLOv11结合全新多尺度线性注意力机制MLAttention(全网独家创新)

1. MLAttention介绍 (1). 多尺度卷积操作&#xff1a;MLAttention通过多尺度卷积操作来增强不同尺度的特征表达能力。采用了多种卷积核尺寸&#xff08;例如5x5、1x7、7x1、1x11、11x1、1x21、21x1&#xff09;的深度可分离卷积来捕捉不同感受野的特征。较小的卷积核擅长捕捉细…