C++优先队列——priority_queue,函数对象,labmda表达式,pair等

2024-03-29 07:04

本文主要是介绍C++优先队列——priority_queue,函数对象,labmda表达式,pair等,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

头文件:#include<queue>

内部使用堆来实现,在需要或得最大的几个值或最小的几个值而不关心整个数组的顺序时非常好用。

用法:

priority_queue<int, vector<int>, greater<int>>q;
第一个参数为堆中存储的元素。

第二个参数为底层使用的存储结构,默认使用vector。

第三个参数为优先队列中元素的比较方式的类。如果是小根堆则为greater,大根堆为less;less、greater二者为仿函数,即把类当作函数使用,本质上为类,内部重载了()运算符,所以可以当作函数。

如果堆中存储的是int元素,则只需要传入less或greater即可,less<T>来定义大顶堆,
greater<T>来定义小顶堆,不需要我们手动实现。

如果传入的是其他复杂类型,则需要我们手动实现比较类。

参考下面这篇文章:

http://t.csdnimg.cn/04qeZ

lambda表达式的详细信息可参考下面这篇:http://t.csdnimg.cn/42OXw

刷题时遇到一道题,

给定两个以 非递减顺序排列 的整数数组 nums1 和 nums2 , 以及一个整数 k 

定义一对值 (u,v),其中第一个元素来自 nums1,第二个元素来自 nums2 

请找到和最小的 k 个数对 (u1,v1) (u2,v2)  ...  (uk,vk) 。

暂未想到合适的解决方案,刚好这题在堆这一章里面,于是考虑使用堆实现。

class cmp
{
public:bool operator()(pair<int,int>&p1,pair<int,int>&p2){return p1.first+p1.second<p2.first+p2.second;}
};class Solution {
public:vector<vector<int>> kSmallestPairs(vector<int>& nums1, vector<int>& nums2, int k) {priority_queue<pair<int,int>,vector<pair<int,int>>,cmp>q;vector<vector<int>>res;for(int i=0;i<nums1.size();i++){for(int j=0;j<nums2.size();j++){if(q.size()<k)q.push(make_pair(nums1[i],nums2[j]));else if(nums1[i]+nums2[j]<q.top().first+q.top().second){q.pop();q.push(make_pair(nums1[i],nums2[j]));}}}while(k--){vector<int>temp;temp.push_back(q.top().first);temp.push_back(q.top().second);res.push_back(temp);q.pop();}return res;}
};

大顶堆小顶堆巧记:在cmp判断函数中,总是返回右边的,即p2。如果是>,则右边较小,为小顶堆。如果是<,则右边较大,为大顶堆。

上述代码中就是使用了大顶堆,大顶堆的数量不超过k,当来了一个新的元素对,将该元素对之和与堆顶元素之和作比较,如果小于堆顶元素之和,说明堆顶还不是最小的k个之一,将堆顶弹出,插入当前元素对。

注:关于pair:函数定义时参数使用pair<int, int>& p1。使用p1.first , p1.second来获取其中的元素。使用pair<int,int>p=make_pair(q.top().first,q.top().second);,也可以直接将make_pair传入函数参数中。

虽然最后只通过了20/30的测试用例,但在数据量较小时也不失为一种方法,且对priority_queue以及函数对象、lambda表达式有了更深刻的认识。

也可以使用lambda表达式:

        auto cmp=[](pair<int,int>&p1,pair<int,int>&p2){return p1.first+p1.second<p2.first+p2.second;};priority_queue<pair<int,int>,vector<pair<int,int>>,decltype(cmp)>q(cmp);

上述题目正解:

class Solution {
public:vector<vector<int>> kSmallestPairs(vector<int>& nums1, vector<int>& nums2, int k) {auto cmp = [&nums1, &nums2](const pair<int, int> & a, const pair<int, int> & b) {return nums1[a.first] + nums2[a.second] > nums1[b.first] + nums2[b.second];};int m = nums1.size();int n = nums2.size();vector<vector<int>> ans;   priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(cmp)> pq(cmp);for (int i = 0; i < min(k, m); i++) {pq.emplace(i, 0);}while (k-- > 0 && !pq.empty()) {auto [x, y] = pq.top(); pq.pop();ans.emplace_back(initializer_list<int>{nums1[x], nums2[y]});if (y + 1 < n) {pq.emplace(x, y + 1);}}return ans;}
};

整体思路相似,都是使用堆。不过该程序堆存储的是数组的索引,便于获得后面索引的值。

在一开始时将0,0  1,0  2,0  3,0......i,0加入堆。每次出堆时,仅仅将i,j+1入堆(事实上i,j入堆下一个可能最小的是i+1,j或i,j+1,但是如果二者都入堆有可能出现重复,即i+1,j+1重复入堆。所以一开始将0,j全部入堆,每次出堆时仅将i,j+1入堆即可,直到结果集中有k个元素。)

这篇关于C++优先队列——priority_queue,函数对象,labmda表达式,pair等的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/857924

相关文章

PostgreSQL中rank()窗口函数实用指南与示例

《PostgreSQL中rank()窗口函数实用指南与示例》在数据分析和数据库管理中,经常需要对数据进行排名操作,PostgreSQL提供了强大的窗口函数rank(),可以方便地对结果集中的行进行排名... 目录一、rank()函数简介二、基础示例:部门内员工薪资排名示例数据排名查询三、高级应用示例1. 每

全面掌握 SQL 中的 DATEDIFF函数及用法最佳实践

《全面掌握SQL中的DATEDIFF函数及用法最佳实践》本文解析DATEDIFF在不同数据库中的差异,强调其边界计算原理,探讨应用场景及陷阱,推荐根据需求选择TIMESTAMPDIFF或inte... 目录1. 核心概念:DATEDIFF 究竟在计算什么?2. 主流数据库中的 DATEDIFF 实现2.1

MySQL中的LENGTH()函数用法详解与实例分析

《MySQL中的LENGTH()函数用法详解与实例分析》MySQLLENGTH()函数用于计算字符串的字节长度,区别于CHAR_LENGTH()的字符长度,适用于多字节字符集(如UTF-8)的数据验证... 目录1. LENGTH()函数的基本语法2. LENGTH()函数的返回值2.1 示例1:计算字符串

c++ 类成员变量默认初始值的实现

《c++类成员变量默认初始值的实现》本文主要介绍了c++类成员变量默认初始值,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录C++类成员变量初始化c++类的变量的初始化在C++中,如果使用类成员变量时未给定其初始值,那么它将被

C++中NULL与nullptr的区别小结

《C++中NULL与nullptr的区别小结》本文介绍了C++编程中NULL与nullptr的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编... 目录C++98空值——NULLC++11空值——nullptr区别对比示例 C++98空值——NUL

C++ Log4cpp跨平台日志库的使用小结

《C++Log4cpp跨平台日志库的使用小结》Log4cpp是c++类库,本文详细介绍了C++日志库log4cpp的使用方法,及设置日志输出格式和优先级,具有一定的参考价值,感兴趣的可以了解一下... 目录一、介绍1. log4cpp的日志方式2.设置日志输出的格式3. 设置日志的输出优先级二、Window

MySQL 中的 CAST 函数详解及常见用法

《MySQL中的CAST函数详解及常见用法》CAST函数是MySQL中用于数据类型转换的重要函数,它允许你将一个值从一种数据类型转换为另一种数据类型,本文给大家介绍MySQL中的CAST... 目录mysql 中的 CAST 函数详解一、基本语法二、支持的数据类型三、常见用法示例1. 字符串转数字2. 数字

Python内置函数之classmethod函数使用详解

《Python内置函数之classmethod函数使用详解》:本文主要介绍Python内置函数之classmethod函数使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录1. 类方法定义与基本语法2. 类方法 vs 实例方法 vs 静态方法3. 核心特性与用法(1编程客

Python函数作用域示例详解

《Python函数作用域示例详解》本文介绍了Python中的LEGB作用域规则,详细解析了变量查找的四个层级,通过具体代码示例,展示了各层级的变量访问规则和特性,对python函数作用域相关知识感兴趣... 目录一、LEGB 规则二、作用域实例2.1 局部作用域(Local)2.2 闭包作用域(Enclos

Python实现对阿里云OSS对象存储的操作详解

《Python实现对阿里云OSS对象存储的操作详解》这篇文章主要为大家详细介绍了Python实现对阿里云OSS对象存储的操作相关知识,包括连接,上传,下载,列举等功能,感兴趣的小伙伴可以了解下... 目录一、直接使用代码二、详细使用1. 环境准备2. 初始化配置3. bucket配置创建4. 文件上传到os