【C++初阶】仿函数和priority_queue的模拟实现(附源码)

2023-11-14

一.仿函数

仿函数,顾名思义就是模仿函数,它其实是一个类,类里面重载了运算符(),在调用这个重载的运算符时,让我们感觉是调用函数一样,可以说相当于C语言里的函数指针一样,但是函数指针的可读性不好,不如仿函数。

仿函数的特点

1.仿函数即使定义相同,也可能有不同的类型;

2.仿函数通常比一般函数速度快;

3.仿函数使程序代码变简单。

例子

template<class T>
class Less
{
public:
	bool operator()(const T& x, const T& y)
	{
		return x < y;
	}
};

int main()
{
	int a = 10, b = 20;
	Less<int> Le;
	cout << Le(a, b) << endl;   //像函数一样调用

	return 0;
}

二.模拟实现priority_queue

priority_queue即优先级队列,它的底层是一个堆,且默认是大堆,所以在模拟实现优先级队列时要先建堆,不了解的话可以参考文章:堆的实现

相关接口:

 

源码

//less是库里的仿函数, 用来判断左操作数是否小于右操作数,可以用来建大堆
//greater也是库里的仿函数,比较左操作数是否大于右操作数,可以用来建小堆
//库里比较的是内置类型的大小,如果是自定义类型,那么自定义类型里就必须要重载 > 或 < 运算符
template<class T,class Containers=vector<T>,class Compare=less<T>> 
	class priority_queue
	{
	private:
        //默认建大堆
		//向下调整
		void AdjustDown(int parent)
		{
			Compare com;
			int child = 2 * parent + 1;
			while (child < _con.size())
			{
				if (child + 1 < _con.size() && com(_con[parent], _con[child+1]))
				{
					child++;
				}
				
				if (com(_con[parent], _con[child]))
				{
					std::swap(_con[parent], _con[child]);
					parent = child;
					child = 2 * parent + 1;
				}
				else
					break;
			}
		}

		//向上调整
		void AdjustUp(int child)
		{
			Compare com;
			int parent = (child - 1) / 2;
			while (child > 0)
			{
				if (com(_con[parent], _con[child]))
				{
					std::swap(_con[parent], _con[child]);
					child = parent;
					parent = (child - 1) / 2;
				}
				else
					break;
			}
		}
	public:
		priority_queue()   //默认构造
		{
			;
		}
		template<class Inputiterator>   //迭代器区间构造
		priority_queue(Inputiterator first, Inputiterator last)
		{
			while (first != last)   //插入数据
			{
				_con.push_back(*first);
				first++;
			}

			//建堆
			for (size_t i = (_con.size() - 1 - 1) / 2; i >= 0; i--)
			{
				AdjustDown(i);
			}
		}

		void push(const T& x)   //插入
		{
			_con.push_back(x);
			//AdjustDown(0);
			AdjustUp(_con.size() - 1);
		}

		void pop()
		{
			std::swap(_con[0], _con[_con.size() - 1]);  //第一个元素和最后一个元素交换
			_con.pop_back();

			AdjustDown(0);
		}

		const T& top()  const  //取堆顶数据
		{
			return _con[0];
		}

		bool empty()
		{
			return _con.size() == 0;
		}

		size_t size() 
		{
			return _con.size();
		}

	private:
		Containers _con;
	};

三.例题:数组中K个最大的元素

链接:

数组中第K个最大的元素

题目再现: 

题解:

这个就类似于topk问题,我们可以先建个大堆(大堆是排降序,小堆是排升序),然后出掉前 K-1 个数据,此时堆顶数据即最终的答案,并返回。

之前在C语言那里的时候,还得自己造轮子,手搓一个堆出来,但是C++不用了,直接使用优先级队列priority_queue

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) 
    {
        priority_queue<int> pq;   //建大堆
        for(auto& e:nums)
        {
            pq.push(e);   //插入数据到堆里
        }

        while(--k)   //出掉前k-1个数据
        {
            pq.pop();
        }

        return pq.top();   //返回堆顶数据
    }
};

 


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【C++初阶】仿函数和priority_queue的模拟实现(附源码) 的相关文章

  • Tensorflow 中的自定义资源

    由于某些原因 我需要为 Tensorflow 实现自定义资源 我试图从查找表实现中获得灵感 如果我理解得好的话 我需要实现3个TF操作 创建我的资源 资源的初始化 例如 在查找表的情况下填充哈希表 执行查找 查找 查询步骤 为了促进实施 我
  • 当我单击 C# 中的“取消”按钮时重定向到新页面(Web 部分)

    Cancel button tc new TableCell btnCancel new Button btnCancel Text Cancel btnCancel Click new EventHandler btnCanel Clic
  • 捕获 foreach 条件中抛出的异常

    我有一个foreach在 foreach 本身的条件下循环期间中断的循环 有没有办法try catch抛出异常然后继续循环的项 这将运行几次 直到异常发生然后结束 try foreach b in bees exception is in
  • try-catch 中未处理的异常

    try list from XElement e in d Descendants wix File where e Attribute Name Value Contains temp Name e Parent Parent Attri
  • 调试内存不足异常

    在修复我制作的小型 ASP NET C Web 应用程序的错误时 我遇到了 OutOfMemoryException 没有关于在哪里查看的提示 因为这是一个编译时错误 如何诊断此异常 我假设这正是内存分析发挥作用的地方 有小费吗 Thank
  • 转到 C# WPF 中的第一页

    我正在 WPF 中使用导航服务 为了导航到页面 我使用 this NavigationService Navigate new MyPage 为了返回我使用 this NavigationService GoBack 但是如何在不使用的情况
  • 是否有与 C++11 emplace/emplace_back 函数类似的 C# 函数?

    从 C 11 开始 可以写类似的东西 include
  • 单元测试失败,异常代码为 c0000005

    我正在尝试使用本机单元测试项目在 Visual Studios 2012 中创建单元测试 这是我的测试 TEST METHOD CalculationsRoundTests int result Calculations Round 1 0
  • 组合框项目为空但数据源已满

    将列表绑定到组合框后 其 dataSource Count 为 5 但组合框项目计数为 0 怎么会这样 我习惯了 Web 编程 而且这是在 Windows 窗体中进行的 所以不行combo DataBind 方法存在 这里的问题是 我试图以
  • C# 创建数组的数组

    我正在尝试创建一个将使用重复数据的数组数组 如下所示 int list1 new int 4 1 2 3 4 int list2 new int 4 5 6 7 8 int list3 new int 4 1 3 2 1 int list4
  • C# 编译器如何决定发出可重定向的程序集引用?

    NET Compact Framework 引入了可重定向程序集引用 现在用于支持可移植类库 基本上 编译器会发出以下 MSIL assembly extern retargetable mscorlib publickeytoken 7C
  • “MyClass”的类型初始值设定项引发异常

    以下是我的Windows服务代码 当我调试代码时 我收到错误 异常 CSMessageUtility CSDetails 的类型初始值设定项引发异常 using System using System Collections Generic
  • 在 C 中复制两个相邻字节的最快方法是什么?

    好吧 让我们从最明显的解决方案开始 memcpy Ptr const char a b 2 调用库函数的开销相当大 编译器有时不会优化它 我不会依赖编译器优化 但即使 GCC 很聪明 如果我将程序移植到带有垃圾编译器的更奇特的平台上 我也不
  • 32位PPC rlwinm指令

    我在理解上有点困难rlwinmPPC 汇编指令 旋转左字立即然后与掩码 我正在尝试反转函数的这一部分 rlwinm r3 r3 0 28 28 我已经知道什么了r3 is r3在本例中是一个 4 字节整数 但我不确定这条指令到底是什么rlw
  • 无法使用 Ninject 将依赖项注入到从 Angular 服务调用的 ASP.NET Web API 控制器中

    我将 Ninject 与 ASP NET MVC 4 一起使用 我正在使用存储库 并希望进行构造函数注入以将存储库传递给其中一个控制器 这是实现 StatTracker 接口的上下文对象 EntityFramework public cla
  • Fluent NHibernate 日期时间 UTC

    我想创建一个流畅的 nhibernate 映射来通过以下方式映射 DateTime 字段 保存时 保存 UTC 值 读取时 调整为本地时区值 实现此映射的最佳方法是什么 就我个人而言 我会将日期存储在 UTC 格式的对象中 然后在读 写时在
  • 如何在 GCC 5 中处理双 ABI?

    我尝试了解如何克服 GCC 5 中引入的双重 ABI 的问题 但是 我没能做到 这是一个重现错误的非常简单的示例 我使用的GCC版本是5 2 如您所见 我的主要函数 在 main cpp 文件中 非常简单 main cpp include
  • 在基类集合上调用派生方法

    我有一个名为 A 的抽象类 以及实现 A 的其他类 B C D E 我的派生类持有不同类型的值 我还有一个 A 对象的列表 abstract class A class B class A public int val get privat
  • boost::program_options:带有固定和可变标记的参数?

    是否可以在 boost program options 中使用此类参数 program p1 123 p2 234 p3 345 p12 678 即 是否可以使用第一个标记指定参数名称 例如 p 后跟一个数字 是动态的吗 我想避免这种情况
  • Swagger 为 ASP.CORE 3 中的字典生成错误的 URL

    当从查询字符串中提取的模型将字典作为其属性之一时 Swagger 会生成不正确的 URL 如何告诉 Swagger 更改 URL 中字典的格式或手动定义输入参数模式而不自动生成 尝试使用 Swashbuckle 和 NSwag 控制器 pu

随机推荐

  • 区块链技术医疗卫生领域运用综述————医药供应链(2019年4月份)

    区块链技术医疗卫生领域运用综述 医药供应链 FJTCM区块链技术开发学习小组 时间 2019 04 24 目录 摘要 1 Abstract 2 引言 3 一 医药冷链物流现状分析 4 1 发展机遇 4 2 存在的问题
  • unity,如何通过协程,将物体的颜色逐渐变浅,慢慢消失

    介绍 unity 如何通过协程 将物体的颜色逐渐变浅 慢慢消失 方法 IEnumerator Stop while sprite color a gt 0 sprite color new Color sprite color r spri
  • 论文笔记:CVPR 2022 Cross-Domain Adaptive Teacher for Object Detection

    摘要 我们解决了对象检测中的域适应任务 其中有注释的源域和没有注释的感兴趣的目标域之间存在域间隙 注 在一个数据集上训练模型 再另外一个数据集上进行预测性能下降很大 在一个数据集上训练好的模型无法应用在另一个数据集上 作为一种有效的半监督学
  • opencv轻松入门面向pythonpdf下载_小白入门到大佬都在看的Python电子书奉上!最好用的PDF...

    关注 转发 最后私信小编 资料 即可获取小编准备的pythonPDF资料啦 电子版的哦 只赠送前500位哦 书籍简介 像计算机科学家一样思考Python 第2版 本书以培养读者以计算机科学家一样的思维方式来理解Python语言编程 贯穿全书
  • sqlmap工具学习记

    学习时间2022 7 20 既要不辜负别人也要对得起自己 1 python2 7版本下载安装 因为sqlmap依赖环境是2 7所以我们下载2 7版本 进入下载官网Download Python Python org 选择你要下载的版本 选择
  • python爬虫之JS混淆加密、字体反爬

    1 JS混淆加密 我们之前爬取有道翻译的翻译内容时 我们通过fiddler抓取url地址时 我们发现如果我们直接将相关参数传入 会报错 只是因为 某些参数是变化的 因此 我们需要解读JS文件 取得相关参数的生成算法 利用python生成参数
  • 电流源等效噪声公式

  • 华为OD机试真题-单词倒序【2023Q1】【JAVA、Python、C++】

    题目描述 输入单行英文句子 里面包含英文字母 空格以及 三种标点符号 请将句子内每个单词进行倒序 并输出倒序后的语句 输入描述 输入字符串S S的长度1 N 100 输出描述 输出逆序后的字符串 补充说明 标点符号左右的空格 0 单词间空格
  • obb vtk 定点坐标_vtk学习笔记 --- 显示坐标系

    有的时候 在显示三维物体时 我们希望知道当前场景对应的坐标系位置或者方向 这样在旋转物体的时候 就能够很清楚地看到当前正对这视野的是什么面xy平面 还是y轴等信息了 在vtk库中有一个vtkAxesActor负责显示坐标系 在查阅了vtk的
  • OpenMAX学习资料收集

    OpenMAX框架拆解与实现 OpenMax OMX 开发入门 OpenMax人口 OpenMAX IL spec手册下载 https www khronos org files openmax il spec 1 0 pdf OpenMA
  • 重要思想总结

    重要思想总结 求二进制序列中1的个数 检测num中某一位是0还是1 不创建临时变量交换值 判断数值的位数 判断数值的位数 获取数值的每一位数 把一个整数的二进制位的奇数位和偶数位交换 将个位数 十位数 百位数 组成一个完整的数 找素数 将秒
  • centos dhcp服务器文件,centos dhcp服务器配置

    centos dhcp服务器配置 内容精选 换一换 简要介绍PHP FPM PHP FastCGI Process Manager PHP FastCGI进程管理器 用于管理PHP进程池的软件 用于接受web服务器的请求 PHP FPM提供
  • Django错误(1146,Table 'xxxx.django_session' doesn't exist")

    原文链接 https blog csdn net BlackListMan article details 82620144 出现这种错误先检查 数据库连接设置是否成功 在setting py同级文件中的 init py 中是否添加了数据库
  • SecureCRT遇到打开错误的时候

    我的解决办法 因为我用的是安装版的 我的操作是 1 删除注册表 可查 2 关闭所有的关于securecrt的进程 通过 任务管理器 的 详细信息 仔细检查关闭 3 一般就搞定了 4 参考文档 http blog csdn net lishe
  • MyBatis Plus多表联查方法

    MyBatis Plus是一款针对MyBatis框架的增强工具 它提供了很多方便的方法来实现多表联查 你可以使用MyBatis Plus的selectPage方法来实现多表联查 该方法接收一个QueryWrapper参数 你可以在Query
  • keyCode键盘码

    下次记不住了来查查吧 keyCode 8 BackSpace BackSpace keyCode 9 Tab Tab keyCode 12 Clear keyCode 13 Enter keyCode 16 Shift L keyCode
  • linux启动kvm虚拟机,如何在Linux中使用KVM(基于内核的虚拟机)创建虚拟机 - 第1部分...

    使用KVM在Linux中创建虚拟机 第1部分 本教程讨论KVM介绍 部署以及如何使用它在RedHat为基础的分布 如RHEL CentOS7和Fedora 21来创建虚拟机 什么是KVM KVM或 基于内核的虚拟机 是面向Linux的英特尔
  • git 恢复本地代码到仓库版本_Repo和Git 版本管理常用命令总结

    1 服务器版本下载 repo init u git 192 168 1 11 i700t 60501010 platform manifest git b froyo almond m M76XXTSNCJNLYA60501010 xml
  • Vue2学习第六篇:事件处理

    一 事件的基本使用 1 使用v on xxx 或 xxx 绑定事件 其中xxx是事件名 2 事件的回调需要配置在methods对象中 最终会在vm上 3 methods中配置的函数 不要用箭头函数 否则this就不是vm了 4 method
  • 【C++初阶】仿函数和priority_queue的模拟实现(附源码)

    一 仿函数 仿函数 顾名思义就是模仿函数 它其实是一个类 类里面重载了运算符 在调用这个重载的运算符时 让我们感觉是调用函数一样 可以说相当于C语言里的函数指针一样 但是函数指针的可读性不好 不如仿函数 仿函数的特点 1 仿函数即使定义相同
Powered by Hwhale