【第九天】C++函数对象/仿函数、谓词、适配器及常见algorithm算法
目录一、函数对象二、谓词1、一元谓词2、二元谓词三、内建函数对象四、适配器1、函数对象 适配器2、函数指针适配器 ptr_fun3、成员函数 作为适配器 mem_fun_ref4、取反适配器五、 常见算法1、遍历算法1for_each遍历算法2transform算法2、查找算法1find算法2find_if算法 条件查找3adjacent_find算法 查找相邻重复元素​4binary_search算法 二分查找法​5count算法 统计元素出现次数​6count_if算法 按条件统计元素出现次数3、排序算法1merge算法 容器元素合并2sort算法 容器元素排序3random_shuffle算法 对指定范围内的元素随机调整次序​4reverse算法 反转指定范围的元素4、拷贝替换算法1copy算法2replace算法3replace_if算法4swap算法 互换两个容器的元素5、算数生成算法1accumulate算法 计算容器元素累计总和2fill算法 向容器中填满元素​6、 集合算法3set_intersection求两个set集合的交集2set_union算法 求两个set集合的并集​编辑3set_difference算法 求两个set集合的差集​编辑六、综合案例一、函数对象重载了函数调用运算符()的类实例化的对象叫函数对象也叫仿函数。如果函数对象 有一个参数 叫一元函数对象/仿函数如果函数对象 有二个参数 叫二元函数对象/仿函数如果函数对象 有三个及以上参数 叫多元函数对象/仿函数注意:1.函数对象(仿函数)是一个类不是一个函数。2.函数对象(仿函数)重裁了()操作符使得它可以像函数一样调用。仿函数概念由来二、谓词返回值为bool类型的普通函数或仿函数都叫谓词。如果谓词 有一个参数 叫一元谓词如果谓词 有二个参数 叫二元谓词一般没有多元谓词1、一元谓词用于查找头文件algorithm提供find_if算法策略2、二元谓词用于排序 头文件algorithm提供sort算法策略#include iostream #includevector #includealgorithm using namespace std; bool myGreater(int n1,int n2) { return n1n2; } class MyGreater { public: bool operator()(int n1,int n2) { return n1n2; } }; void printVectorInt(vectorint v) { vectorint::iterator it; for(itv.begin();it!v.end();it) { cout*it ; } coutendl; } void test() { //sort排序 vectorint v; v.push_back(3); v.push_back(1); v.push_back(5); v.push_back(2); v.push_back(4); printVectorInt(v); sort(v.begin(),v.end());//顺序 printVectorInt(v); //倒序 //sort(v.begin(),v.end(),myGreater); sort(v.begin(),v.end(),MyGreater()); printVectorInt(v); } int main(int argc, char *argv[]) { test(); return 0; }关键代码及运行结果三、内建函数对象定义系统提供好的 函数对象。实质是类模板6个算数类函数对象,除了negate是一元运算其他都是二元运算templateclass T T plusT//加法仿函数templateclass T T minusT//减法仿函数templateclass T T multipliesT//乘法仿函数templateclass T T dividesT//除法仿函数templateclass T T modulusT//取模仿函数templateclass T T negateT//取反仿函数6个关系运算类函数对象,每一种都是二元运算templateclass T bool equal_toT//等于templateclass T bool not_equal_toT//不等于templateclass T bool greaterT//大于templateclass T bool greater_equalT//大于等于templateclass T bool lessT//小于templateclass T bool less_equalT//小于等于逻辑运算类运算函数,not为一元运算其余为二元运算templateclass T bool logical_andT//逻辑与templateclass T bool logical_orT//逻辑或templateclass T bool logical_notT//逻辑非一元谓词查找用内建函数实现将二元谓词排序用内建函数对象实现四、适配器适配器 为算法 提供接口。1、函数对象 适配器2、函数指针适配器 ptr_fun3、成员函数 作为适配器 mem_fun_ref4、取反适配器not1函数一元取反not2函数 二元取反五、 常见算法头文件#includealgorithm适用于随机访问迭代器。1、遍历算法1for_each遍历算法遍历容器元素for_each(iterator beg, iterator end, _callback);param beg 开始迭代器param end 结束迭代器param _callback 函数回调或者函数对象return 函数对象2transform算法将指定容器区间元素搬运到另一容器中transform(iterator beg1, iterator end1, iterator beg2, _callbakc)注意 : transform 不会给目标容器分配内存所以需要我们提前分配好内存param beg1 源容器开始迭代器param end1 源容器结束迭代器param beg2 目标容器开始迭代器param _cakkback 回调函数或者函数对象return 返回目标容器迭代器2、查找算法1find算法查找元素find(iterator beg, iterator end, value)param beg 容器开始迭代器param end 容器结束迭代器param value 查找的元素return 返回查找元素的位置查找基本类型数据查找自定义类型数据#include iostream #includestring #includevector #includealgorithm using namespace std; class Person { friend void test(); private: int num; string name; public: Person(){} Person(int num,string name) { this-numnum; this-namename; } //重载提供比较策略 bool operator(const Person ob) { return ((ob.namethis-name)(ob.numthis-num)); } }; void test() { vectorPerson v; v.push_back(Person(3,tom)); v.push_back(Person(1,bob)); v.push_back(Person(5,张三)); v.push_back(Person(2,小明)); v.push_back(Person(1,小红)); vectorPerson::iterator ret; //find 查找自定义数据类型 需要重载 retfind(v.begin(),v.end(),Person(5,张三)); if(ret!v.end()) { cout找到元素:(*ret).num (*ret).nameendl; } } int main(int argc, char *argv[]) { test(); return 0; }主函数代码及运行结果2find_if算法 条件查找find_if(iterator beg, iterator end, _callback)param beg 容器开始迭代器param end 容器结束迭代器param callback 回调函数或者谓词(返回bool类型的函数对象)return bool 查找返回true 否则false3adjacent_find算法 查找相邻重复元素adjacent_find(iterator beg, iterator end, _callback);param beg 容器开始迭代器param end 容器结束迭代器param _callback 回调函数或者谓词(返回bool类型的函数对象)return 返回相邻元素的第一个位置的迭代器4binary_search算法 二分查找法bool binary_search(iterator beg, iterator end, value);注意: 必须在有序序列中使用在无序序列中不可用。param beg 容器开始迭代器param end 容器结束迭代器param value 查找的元素return bool 查找返回true 否则false5count算法 统计元素出现次数count(iterator beg, iterator end, value);param beg 容器开始迭代器param end 容器结束迭代器param value 要统计的元素return int返回元素个数6count_if算法 按条件统计元素出现次数param beg 容器开始迭代器param end 容器结束迭代器param callback 回调函数或者谓词(返回bool类型的函数对象)return int返回元素个数3、排序算法1merge算法 容器元素合并merge算法 容器元素合并并存储到另一容器中merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterat or dest)注意:两个容器必须是有序的合并后的容器仍然有序目标容器需预留空间。param beg1 容器1开始迭代器param end1 容器1结束迭代器param beg2 容器2开始迭代器param end2 容器2结束迭代器param dest 目标容器开始迭代器2sort算法 容器元素排序sort算法 容器元素排序 sort(iterator beg, iterator end, _callback)param beg 容器1开始迭代器param end 容器1结束迭代器param _callback 回调函数或者谓词(返回bool类型的函数对象)3random_shuffle算法 对指定范围内的元素随机调整次序random_shuffle(iterator beg, iterator end)param beg 容器开始迭代器param end 容器结束迭代器4reverse算法 反转指定范围的元素reverse(iterator beg, iterator end)param beg 容器开始迭代器param end 容器结束迭代器4、拷贝替换算法1copy算法copy算法 将容器内指定范围的元素拷贝到另一容器中copy(iterator beg, iterator end, iterator destparam beg 容器开始迭代器param end 容器结束迭代器param dest 目标起始迭代器copy提升2replace算法将容器内指定范围的旧元素修改为新元素replace(iterator beg, iterator end, oldvalue, newvalue)param beg 容器开始迭代器param end 容器结束迭代器param oldvalue 旧元素param oldvalue 新元素3replace_if算法replace_if算法 将容器内指定范围满足条件的元素替换为新元素replace_if(iterator beg, iterator end, _callback, newvalue)param beg 容器开始迭代器param end 容器结束迭代器param callback函数回调或者谓词(返回Bool类型的函数对象)param oldvalue 新元素4swap算法 互换两个容器的元素swap(container c1, container c2)param c1容器param c2容器25、算数生成算法1accumulate算法 计算容器元素累计总和accumulate(iterator beg, iterator end, value)param beg 容器开始迭代器param end 容器结束迭代器param value追加值 求和完后 value2fill算法 向容器中填满元素fill(iterator beg, iterator end, value)param beg 容器开始迭代器param end 容器结束迭代器param value 填充元素6、 集合算法3set_intersection求两个set集合的交集set_intersection(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest)注意:两个集合必须是有序序列param beg1 容器1开始迭代器param end1 容器1结束迭代器param beg2 容器2开始迭代器param end2 容器2结束迭代器param dest 目标容器开始迭代器return 目标容器的最后元素下一位置的迭代器地址2set_union算法 求两个set集合的并集set_union(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest)注意:两个集合必须是有序序列param beg1 容器1开始迭代器param end1 容器1结束迭代器param beg2 容器2开始迭代器param end2 容器2结束迭代器param dest 目标容器开始迭代器return 目标容器的最后元素下一位置的迭代器地址3set_difference算法 求两个set集合的差集set_difference(iterator beg1, iterator end1, iterator beg2, iterator end 2, iterator dest)注意:两个集合必须是有序序列param beg1 容器1开始迭代器param end1 容器1结束迭代器param beg2 容器2开始迭代器param end2 容器2结束迭代器param dest 目标容器开始迭代器return 目标容器的最后一个元素的迭代器地址六、综合案例某市举行一场演讲比赛共有24个人参加。比赛共三轮前两轮为淘汰赛第三轮为决 赛。比赛方式分组比赛每组6个人选手每次要随机分组进行比赛第一轮分为4个小组每组6个人。比如编号为: 100-123. 整体进行抽签 draw后顺序演讲。当小组演讲完后淘汰组内排名最后的三个选手然后 继续下一个小组的比赛。第二轮分为2个小组每组6人。比赛完毕淘汰组内排名最后的三个选手然后继续下一 个小组的比赛。第三轮只剩下1组6个人本轮为决赛选出前三名。比赛评分10个评委打分去除最 低、最高分求平均分每个选手演讲完由10个评委分别打分。该选手的最终得分是去掉一 个最高分和一个最低分求得剩下的8个成绩的平均分。选手的名次按得分降序排列。需求分析 1) 产生选手 ABCDEFGHIJKLMNOPQRSTUVWX 姓名、得分选手编 号实现思路:需要把选手信息、选手得分信息、选手比赛抽签信息、选手的晋级信息保存在容器中需要涉及到各个容器的选型。选手可以设计一个类Speaker姓名和得分所有选手的编号可以单独放在一个vector容器中做抽签用-所有选手编号和选手信息可以放在map容器内。#include iostream #includestring #includevector #includemap #includealgorithm #includestdlib.h #includetime.h #includedeque using namespace std; class player { friend void play(int index,vectorint v, mapint,player m, vectorint v1); private: int num; string name; float score[3]; public: player(){} player(int num,string name) { this-namename; this-numnum; } }; void createPlayer(vectorint v,mapint,player m) { string seednameABCDEFGHIJKLMNOPQRSTUVWX; for(int i0;i24;i) { string tmpname选手; tmpnameseedname[i]; int numi; v.push_back(num); m.insert(make_pair(num,player(num,tmpname))); } } void play(int index,vectorint v,mapint,player m,vectorint v1) { //选手编号随机分组 srand(time(NULL)); random_shuffle(v.begin(),v.end()); multimapfloat,int,greaterfloat mul;//存放每组的分数‐‐编号 vectorint::iterator itv.begin(); int count0; cout-------第index轮比赛-------endl; //每名选手比赛 for(;it!v.end();it) { count; //定义deque容器 存放评委打分 dequefloat d; int i0; for(;i10;i) { d.push_back((float)(rand()%4160)); } //排序 sort(d.begin(),d.end()); //去掉最高、最低分 d.pop_front(); d.pop_back(); //求平均分 float avgaccumulate(d.begin(),d.end(),0)/d.size(); //将平均分 赋值给m中选手 m[*it].score[index-1]avg; mul.insert(make_pair(avg, *it)); if(count%60)//刚好一组 { cout\t第count/6组的晋级名单:endl; int i0; multimapfloat,int,greaterfloat::iterator mitmul.begin(); for(;i3;i,mit) { v1.push_back( (*mit).second); cout\t\t(*mit).second (*mit).firstendl; } cout\t第count/6组的得分情况:endl; mitmul.begin(); for(int i0;i6;i,mit) { int num(*mit).second; cout\t\tnum m[num].name m[num].score[index-1]endl; } mul.clear(); } } } void test() { vectorint v; mapint,player m; //创建选手 createPlayer(v,m); vectorint v1;//存放晋级选手的编号 play(1,v,m,v1); vectorint v2;//存放晋级选手的编号 play(2,v1,m,v2); vectorint v3;//存放晋级选手的编号 play(3,v2,m,v3); } int main(int argc, char *argv[]) { test(); return 0; }运行结果

相关新闻

synchronized 锁的用法

synchronized 锁的用法

目录 一. synchronized 实现同步代码块 二. synchronized 同步代码块的特点 三. synchronized 同步代码块的使用细节 四. synchronized 实现同步方法 五. 同步方法的注意事项 六. StringBuffer类 与 synchronized 的关系 一. synchronized 实现同步代码块 在 Java 中&am…

2026/7/16 18:29:37阅读更多 →
Java 中 final、finally 与 finalize():语义、底层机制与常见误区

Java 中 final、finally 与 finalize():语义、底层机制与常见误区

目录 一. finalize() 详解 1.1 finalize 方法是什么? 1.2 finalize 方法的作用? 1.3 为什么强烈不建议在 finalize 方法中进行资源的释放和清理工作 1.4 版本说明 二. finally 详解 2.1 基本语义 2.2 return 遇到 finally 2.3 finally 也可能掩…

2026/7/16 18:29:37阅读更多 →
数据库 explain 关键字解析

数据库 explain 关键字解析

目录 一. explain 概述 二. explain 关键字的使用方式 三. explain 的版本迭代 四. explain 只分析SQL语句,不执行SQL语句 五. explain 输出结果中各个字段的含义 六. type 表示检索表数据的方式 七. key_len表示使用的索引的长度 八. rows 表示预估读取到的…

2026/7/16 18:29:37阅读更多 →
WMPageController 使用教程

WMPageController 使用教程

WMPageController 使用教程 【免费下载链接】WMPageController An easy solution to page controllers like NetEase News 项目地址: https://gitcode.com/gh_mirrors/wm/WMPageController 1. 项目介绍 WMPageController 是一个开源的 iOS 项目,旨在为开发者…

2026/7/16 19:24:41阅读更多 →
Qt,C++海康2D工业相机二次开发

Qt,C++海康2D工业相机二次开发

1.先下载海康的MVS客户端,下载安装后路径下会自动有相应的安装包,包括头文件以及lib库文件 海康机器人-机器视觉-下载中心 2.在pro项目文件里面配置库文件以及头文件 INCLUDEPATH $$PWD/Hik_Includes DEPENDPATH $$PWD/Hik_Includes LIBS -L$$PWD/L…

2026/7/16 19:24:41阅读更多 →
AI直接“上手“数据库:电科金仓KES MCP Server落地实操

AI直接“上手“数据库:电科金仓KES MCP Server落地实操

“orders这张表上都有哪些字段?索引是怎么建的?” “帮我看看这条SQL慢在哪里。” “如果给user_id和status加个联合索引,执行计划会变吗?” 这些过去要让DBA或开发人员来回切工具、复制粘贴才能回答的问题,如今在TRAE…

2026/7/16 19:24:40阅读更多 →
【JAVA毕设源码分享】基于Java的停车场管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

【JAVA毕设源码分享】基于Java的停车场管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/16 19:24:40阅读更多 →
【JAVA毕设源码分享】基于JavaWeb的点餐系统的设计与实现(程序+文档+代码讲解+一条龙定制)

【JAVA毕设源码分享】基于JavaWeb的点餐系统的设计与实现(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/16 19:24:40阅读更多 →
技术型创始人的市场感知框架:从趋势信号到商业机会的系统化转化

技术型创始人的市场感知框架:从趋势信号到商业机会的系统化转化

技术型创始人的市场感知框架:从趋势信号到商业机会的系统化转化 一、技术直觉的两面性:为什么技术型创始人容易错判市场 技术出身的创始人,最危险的时刻不是代码写不出来,而是用技术视角替代市场判断。一个典型的决策模式是&#…

2026/7/16 19:19:40阅读更多 →
VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异当你在VSCode中启动一个新的TypeScript项目时,第一个技术决策往往从安装方式开始。这个看似简单的选择——全局安装还是项目本地安装——实际上会深刻影响你的开发流程、团队协作和…

2026/7/16 8:28:11阅读更多 →
智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手 【免费下载链接】zhihuishu 智慧树刷课插件,自动播放下一集、1.5倍速度、无声 项目地址: https://gitcode.com/gh_mirrors/zh/zhihuishu 智慧树刷课插件是一款专为智慧树在线教育平台设计的Chrome浏…

2026/7/16 6:53:04阅读更多 →
Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL 你是否在GOG或Epic Games Store购买了心仪的游戏…

2026/7/16 12:02:41阅读更多 →
A--10 Codex Review与GitHub PR工作流实战指南:从代码审查到安全合并

A--10 Codex Review与GitHub PR工作流实战指南:从代码审查到安全合并

摘要:本文系统讲解如何利用Codex App的Review功能与GitHub PR工作流,实现从代码修改到安全合并的完整流程。涵盖Review面板深度使用、/review命令实战、GitHub Connector配置、PR描述撰写技巧,以及常见问题排查方法。通过多个实战案例和流程图,帮助开发者建立高效的AI辅助代…

2026/7/16 0:00:38阅读更多 →
遗传算法解5皇后问题:从Hello World到工业优化的进化实验室

遗传算法解5皇后问题:从Hello World到工业优化的进化实验室

1. 项目概述:为什么用遗传算法解5皇后问题,而不是直接回溯?我带过十几届算法课,也给不少初创团队做过AI架构咨询。每次讲到组合优化问题,学生和工程师的第一反应永远是“写个回溯试试”。这没错——55棋盘上找所有合法…

2026/7/16 0:00:38阅读更多 →
5.1V稳压管输出为何只有4.7V?工作电流与负载影响分析

5.1V稳压管输出为何只有4.7V?工作电流与负载影响分析

前几天调试一个简单的电源模块,用到了5.1V稳压管。电路接好,上电测试,万用表一量——输出居然只有4.7V。第一反应是稳压管坏了,换了一个新的,结果还是4.7V。这让我想起很多初学者都会遇到的困惑:明明标称5.…

2026/7/16 0:00:38阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/15 15:50:47阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/16 8:58:42阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/16 17:10:26阅读更多 →