算法库里的heap算法,仿函数和模版进阶(续)

文章目录

  • 算法库里面的heap
  • 仿函数
  • 模版
    • 非类型模版参数
    • array
    • 特化
      • 函数模版的特化
      • 类模版的特化
  • 分离编译

算法库里面的heap

  • sort_heap是算法库里的函数,前提要求是堆才能排序
  • is_heap判断是否是堆
  • make_heap建堆算法
int main()
{int a[5] = { 10,19,27,39,19 };std::vector<int> v(a, a + 5);sort(a, a + 5);// 虽然is_heap要求参数是迭代器,// 但是可以是数组因为数组空间是连续的,原生指针也可以是天然的迭代器cout << is_heap(v.begin(), v.end()) << endl;cout << is_heap(a, a + 5) << endl;make_heap(v.begin(), v.end());// 默认建大堆for (auto e : v){cout << e << " ";}cout << endl;cout << is_heap(v.begin(), v.end()) << endl;// 排的是升序sort_heap(v.begin(), v.end());for (auto e : v){cout << e << " ";}cout << endl;return 0;
}

仿函数

greater< int >和less< int >是不需要我们自己写的,functional 这个头文件中包含有

有些场景需要我们自己写仿函数

  1. 类类型不支持比较大小
  2. 类类型支持比较大小,但比较的逻辑不是你想要的

底层是按指针比的,先new和后new的是随机的,它的逻辑比较大小不是你想要的,所以要自己写一个仿函数比较大小

// 正确写法
class DateLess
{
public:bool operator()(Date* p1, Date* p2){return *p1 < *p2;}
};wbc::priority_queue<Date*,vector<Date*>,DateLess> q2;q2.push(new Date(2018, 1, 2));
q2.push(new Date(2018, 1, 3));
q2.push(new Date(2018, 1, 6));cout << *q2.top() << endl;
q2.pop();cout << *q2.top() << endl;
q2.pop();cout << *q2.top() << endl;
q2.pop();// 错误写法
wbc::priority_queue<Date*> q2;
q2.push(new Date(2018, 1, 2));
q2.push(new Date(2018, 1, 3));
q2.push(new Date(2018, 1, 6));cout << *q2.top() << endl;
q2.pop();cout << *q2.top() << endl;
q2.pop();cout << *q2.top() << endl;
q2.pop();

模版

非类型模版参数

模版参数分为类型参数和非类型参数
非类型模版参数,只要给了非类类型就可以
非类型模版参数可以控制大小,但是它只能用于整形(int,usigned int,short,char,long,bool),其他类型都不可以

// #define N 5
// 对比#define就是可以令每个Stack的N大小不同
// 可以给缺省值
template<size_t N = 10>
class Stack
{private:int _a[N];int _top;
};//template<double P>
//class Stack
//{
//
//};int main()
{// 不给值这样写Stack<> s0;Stack<5> s1;Stack<10> s2;return 0;
}

C++20才支持double作为非类型的模版参数
在这里插入图片描述

array

array需要包array这个头文件
std::array是库里面的一个固定的数组
array在栈上开空间可以一次开出空间,开空间的效率比vector效率高

#include<array>int main()
{// std::array是库里面的一个固定的数组// array的数据在栈上array<int, 10> a1;array<int, 20> a2;// array 和我们写的数组有什么不同呢?// 越界的检查机制不同// a是静态数组,对越界的后两个标记位进行检查,对读不检查,对写会抽查// 读int a[10];cout << a[10] << endl;// 写,可以检查出来// a[10] = 10;// a[11] = 11;// 检查不出来了// a[12] = 20;// a[20] = 30;// array对读和写都检查// array调用的是operator[],里面的assert强制检查了// 而上面的a是指针解引用// cout << a1[11] << endl;// a1[20] = 10;// 数据在堆上vector<int> v(100, 1);// sizeof算的是栈上的空间大小// vector在栈上给了一个buff数组cout << sizeof(v) << endl;cout << sizeof(a1) << endl;return 0;
}

特化

函数模版的特化

在原模版的基础上才有特化

函数模板的特化步骤:

  1. 必须要先有一个基础的函数模板
  2. 关键字template后面接一对空的尖括号<>
  3. 函数名后跟一对尖括号,尖括号中指定需要特化的类型
  4. 函数形参表: 必须要和模板函数的基础参数类型完全相同,如果不同编译器可能会报一些奇
    怪的错误。
// 函数模版
template<class T>
bool lessfunc(const T& left,const T& right)
{return left < right;
}// 函数模版的特化
// Date*
template<>
bool lessfunc<Date*>(Date* const & left, Date* const & right)
{return *left < *right;
}// 函数模版的特化
// const Date*
template<>
bool lessfunc<const Date*>(const Date* const& left,const Date* const& right)
{return *left < *right;
}// 函数模版的特化
//template<>
//bool lessfunc<Date*>(Date* left, Date* right)
//{
//	return *left < *right;
//}// 建议直接写成函数的形式
//bool lessfunc(Date* left, Date* right)
//{
//	return *left < *right;
//}//bool lessfunc(const Date* left,const Date* right)
//{
//	return *left < *right;
//}int main()
{Date d1(2018, 1, 3);Date d2(2018, 1, 3);cout << lessfunc(1, 2) << endl;cout << lessfunc(d1, d2) << endl;Date* p1 = &d1;Date* p2 = &d2;cout << lessfunc(p1, p2) << endl;const Date* p3 = &d1;const Date* p4 = &d2;cout << lessfunc(p3, p4) << endl;// 这两种const没有区别,都是修饰本身int const i = 0;const int j = 0;// 这两种const没有区别,都是修饰本身const int& k = i;int const& p = j;return 0;
}

类模版的特化

全特化指的是模版参数全都给了
偏特化/半特化是指模版参数给了部分
走的优先级:全特化 > 偏特化 > 模版

// 类模版
template<class T1, class T2>
class Data
{
public:Data() { cout << "Data<T1, T2>" << endl; }
private:T1 _d1;T2 _d2;
};// 半特化/偏特化
template<class T1>
class Data<T1, double>
{
public:Data() {cout << "Data<T1,double>" << endl;}
};// 全特化
template<>
class Data<int, char>
{
public:Data(){cout << "Data<int,char>" << endl;}
};template<class T1>
class Data<T1, char>
{
public:Data() { cout << "Data<T1, char>" << endl; }
};int main()
{Data<int, int> d1;// 有半特化在和全特化在走全特化Data<int, char> d2;Data<int, double> d3; Data<int, double> d4;return 0;
}

更进一步的参数限制
限制都是指针的参数
限制都是引用的参数
限制一个是指针一个是引用

// 偏特化
template<typename T1,typename T2>
class Data<T1*, T2*>
{
public:Data() { cout << "Data<T1*, T2*>" << endl; }
};template<typename T1, typename T2>
class Data<T1&, T2&>
{
public:Data() { cout << "Data<T1&, T2&>" << endl; }
};template<typename T1, typename T2>
class Data<T1*, T2&>
{
public:Data() { cout << "Data<T1*, T2&>" << endl; }
};Data<int*, char*> d5;
Data<int&, double&> d6;
Data<int*, double&> d7;
  • 可以用偏特化解决Date*,比较的是指针的问题,转为比较指向的内容
// 偏特化
template<class T>
class Less<T*>
{
public:bool operator()(T* const& x, T* const& y){return *x < *y;}
};wbc::priority_queue<Date*,vector<Date*>,Less<Date*>> q2;
// wbc::priority_queue<Date*> q2;q2.push(new Date(2018, 1, 2));
q2.push(new Date(2018, 1, 3));
q2.push(new Date(2018, 1, 6));cout << *q2.top() << endl;
q2.pop();cout << *q2.top() << endl;
q2.pop();cout << *q2.top() << endl;
q2.pop();wbc::priority_queue<int*> q3;q3.push(new int(2));
q3.push(new int(1));
q3.push(new int(3));cout << *q3.top() << endl;
q3.pop();cout << *q3.top() << endl;
q3.pop();cout << *q3.top() << endl;
q3.pop();
  • 可以自己控制T1是引用还是指针,不用固定的传入
template<typename T1, typename T2>
class Data<T1*, T2&>
{
public:Data() { cout << "Data<T1*, T2&>" << endl;int a = 0;T1* x = &a;T2& y = a;T1 c = a;cout << typeid(x).name() << endl;cout << typeid(y).name() << endl;}// void push(const T1& x);
};Data<int*, int&> d7;
// T1->int
// T2->int

分离编译

模版不支持声明和定义分离,会导致链接错误
分离(.h和.cpp)

链接的时候通过符号表中的地址找到对应的函数
在这里插入图片描述

解决方法:

  1. 在.cpp文件中进行显示实例化
// 显示实例化
template
int Add(const int& left, const int& right);template
double Add(const double& left, const double& right);
  1. 直接在.h中定义模版,用的地方直接有定义,直接实例化,都不需要链接(推荐实现这种)
// 直接在.h中定义
template<class T>
T Add(const T& left, const T& right)
{cout << "Add(const T& left, const T& right)" << endl;return left + right;
}

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

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

相关文章

具身导航如何利用取之不尽的网络视频资源!RoomTour3D:基于几何感知的视频-指令训练调优

作者&#xff1a;Mingfei Han, Liang Ma, Kamila Zhumakhanova, Ekaterina Radionova, Jingyi Zhang, Xiaojun Chang, Xiaodan Liang, Ivan Laptev 单位&#xff1a;穆罕默德本扎耶德人工智能大学计算机视觉系&#xff0c;中山大学深圳校区&#xff0c;悉尼科技大学ReLER实验室…

解决报错:未定义标识符 “M_PI“

问题&#xff1a; 使用C编译&#xff0c;已经用#include <cmath>包含了头文件&#xff0c;但是在使用M_PI时依旧报错说未定义 原因&#xff1a; 在某些编译器中&#xff0c;<cmath> 库中的 M_PI 是一个条件宏&#xff0c;需要 _USE_MATH_DEFINES 宏被定义才能使用。…

TensorFlow深度学习实战(5)——神经网络性能优化技术详解

TensorFlow深度学习实战&#xff08;5&#xff09;——神经网络性能优化技术详解 0. 前言1. 识别 MNIST 手写数字1.1 MNIST 数据集1.2 独热编码1.3 定义神经网络1.4 训练神经网络 2. 构建深度神经网络3. 添加 Dropout 提高模型泛化能力4. 不同优化器对模型性能的影响5. 训练 ep…

代码随想录算法训练营day31

代码随想录算法训练营 —day31 文章目录 代码随想录算法训练营前言一、 56. 合并区间二、738. 单调递增的数字三、968.监控二叉树总结 前言 今天是算法营的第31天&#xff0c;希望自己能够坚持下来&#xff01; 今日任务&#xff1a; ● 56. 合并区间 ● 738.单调递增的数字 …

通过maven命令上传jar包至nexus v3.7.1

1 nexus和maven的简介 1.1 nexus ‌Nexus‌是由Sonatype公司开发的一款强大的制品仓库管理软件&#xff0c;主要用于搭建和管理各种类型的仓库&#xff0c;包括Maven、NuGet、npm等。Nexus支持多种仓库类型&#xff0c;如代理仓库&#xff08;代理互联网中的中央仓库&#xf…

level(三) filterblock

filterblock用于确定某个key是否存在于某个datablock中&#xff0c;在插入一个key到datablock中时也会插入一个key到filterblock中&#xff0c;filterblock中会记录所有的key&#xff0c;并通过布隆过滤器来确定一个key是否存于这个datablock中。下面来看下filterblock的代码&a…

优化 Vue项目中 app.js 文件过大,初始化加载过慢、带宽占用过大等问题

已亲测&#xff0c;绝对有效&#xff0c;底部有改善前后对比图证明。 1.服务器 nginx 增加配置 #开启gzip压缩 gzip on; #设置gzip压缩级别&#xff0c;2级是性价比最高的 gzip_comp_level 2; #设置动态gzip压缩的文件类型 gzip_types text/plain text/css text/javascript a…

浅谈云计算16 | 存储虚拟化技术

存储虚拟化技术 一、块级存储虚拟化基础2.1 LUN 解析2.1.1 LUN 概念阐释2.1.2 LUN 功能特性 2.2 Thick LUN与Thin LUN2.2.1 Thick LUN特性剖析2.2.2 Thin LUN特性剖析 三、块级存储虚拟化技术实现3.1 基于主机的实现方式3.1.1 原理阐述3.1.2 优缺点评估 3.2 基于存储设备的实现…

手摸手实战前端项目CI CD

由于图片和格式解析问题&#xff0c;为了更好阅读体验可前往 阅读原文 CI/CD 是 持续集成&#xff08;Continuous Integration&#xff09; 和 持续交付/部署&#xff08;Continuous Delivery/Continuous Deployment&#xff09; 的缩写&#xff0c;是现代软件开发中的一种自动…

【EI 会议征稿通知】第七届机器人与智能制造技术国际会议 (ISRIMT 2025)

第七届机器人与智能制造技术国际会议 (ISRIMT 2025) 2025 7th International Symposium on Robotics & Intelligent Manufacturing Technology 会议主要围绕“机器人”、“智能制造技术” 等研究领域展开讨论&#xff0c;旨在为机器人与智能制造技术等领域的专家学者、工…

【Linux】信号

目录 一、信号的概念二、信号的产生2.1 通过键盘进行信号的产生2.2 通过系统调用进行信号的产生2.2.1 kill函数2.2.2 raise函数2.2.3 abort函数 2.3 通过异常的方式进行信号的产生2.4 通过软件条件的方式进行信号的产生2.4.1 关闭管道读端2.4.2 alarm函数 2.5 Core Dump&#x…

基于go语言的驾考系统设计与实现

在Internet时代&#xff0c;Internet信息技术已广泛应用于各个领域。 对人们的生活以及学习产生了较大的影响。通过信息技术建立的驾照考试管理系统&#xff0c;利用系统对驾照考试进行统一的管理&#xff0c;能够提驾照考试管理的工作效率&#xff0c;具有重要的现实意义。 本…

鸿蒙打包发布

HarmonyOS应用/元服务发布&#xff08;打包发布&#xff09; https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/ide-publish-app-V13?catalogVersionV13 密钥&#xff1a;包含非对称加密中使用的公钥和私钥&#xff0c;存储在密钥库文件中&#xff0c;格式…

基于Linux系统指令使用详细解析

一 Linux系统常用操作命令编辑快捷 1.1终端快捷键&#xff1a; Ctrl a/Home 切换到命令行开始 Ctrl e/End 切换到命令行末尾 Ctrl l 清除屏幕内容&#xff0c;效果等同于 clear Ctrl u 清除剪切光标之前的内容 Ctrl k 剪切清除光标之后的内容 Ctrl y 粘贴刚才所删…

深度学习-87-大模型训练之预训练和微调所用的数据样式

文章目录 1 大模型训练的阶段1.1 预训练1.1.1 全量预训练1.1.2 二次预训练1.2 微调2 预训练需要的数据2.1 清洗成的文本文档2.2 如何从文本文档学习2.3 常见预训练中文语料库3 微调需要的数据3.1 微调例子一:电商客服场景3.2 微调例子二:行政咨询场景3.3 微调数据长什么样3.3…

基于 STM32 的多功能时间管理器项目

引言 在快节奏的生活中&#xff0c;时间管理显得尤为重要。本项目旨在通过 STM32 开发一个多功能时间管理器&#xff0c;功能包括计时器、闹钟和日历。用户可以方便地设置不同的提醒和计时任务&#xff0c;以更好地管理日常生活和工作。 项目名称 多功能时间管理器 环境准备 …

麦田物语学习笔记:代码链接UI实现时间日期对应转换

基本流程 时间系统UI如下 本篇文章将UI和TimeManager里的数据联系在一起, 1.代码思路 (1)新建TimeUI.cs挂载在GameTime物体上,然后获取它的子物体这些组件来改变里面的数值,所以需要获得Day & Night的子物体Image中的Rect Transform,用于旋转季节的图标;获得Clock每个子物…

HTML文章翻页功能

效果展示&#xff1a; 效果原理&#xff1a; 1、引入CDN 2、绘制文章翻页样式&#xff0c;以及自动分段 3、获取窗口宽高&#xff0c;计算出当前文章总分段&#xff0c;并实现分页 4、完整代码 <!DOCTYPE html> <html><head><meta charset"utf-8&qu…

深度学习电影推荐-CNN算法

文章目录 前言视频演示效果1.数据集环境配置安装教程与资源说明1.1 ML-1M 数据集概述1.1.1数据集内容1.1.2. 数据集规模1.1.3. 数据特点1.1.4. 文件格式1.1.5. 应用场景 2.模型架构3.推荐实现3.1 用户数据3.2 电影数据3.3 评分数据3.4 数据预处理3.5实现数据预处理3.6 加载数据…

代理模式实现

一、概念&#xff1a;代理模式属于结构型设计模式。客户端不能直接访问一个对象&#xff0c;可以通过代理的第三者来间接访问该对象&#xff0c;代理对象控制着对于原对象的访问&#xff0c;并允许在客户端访问对象的前后进行一些扩展和处理&#xff1b;这种设置模式称为代理模…