C++ STL 中提供的算法

1 算法

1.1 for_each()

参数有三个:

  • 首迭代器
  • 尾迭代器
  • 执行的函数

例如如下代码:

#include <algorithm>  //必须包含
#include <vector>
using namespace std;int main() {vector<int> tmp;tmp.push_back(10);tmp.push_back(20);tmp.push_back(30);tmp.push_back(40);for_each(tmp.begin(), tmp.end(), [](int vecVal){cout << vecVal << endl;});return 0;
}

结果是:

1.2 accumulate与reduce 求和

1.2.1 accumulate

std::accumulate为一个求和函数, 在标准头文件中定义<numeric>.

其有四中定义:

  • template< class InputIt, class T >
    T accumulate( InputIt first, InputIt last, T init );
  • template< class InputIt, class T >
    constexpr T accumulate( InputIt first, InputIt last, T init );
  • template< class InputIt, class T, class BinaryOperation >

    T accumulate( InputIt first, InputIt last, T init,

                 BinaryOperation op );
  • template< class InputIt, class T, class BinaryOperation >

    constexpr T accumulate( InputIt first, InputIt last, T init,

                            BinaryOperation op );

函数的作用是把一个序列的元素相加, 而前两个参数InputIt first, InputIt last代表着序列的收尾迭代器, T init代表着和的初始值.(注意, 这个参数是必须要传的, 且必须与要相加的元素类型相同), 最后一个参数代表着自定义的相加法则(如果不传就默认用"+"), 返回值代表着累加的结果.

在accumulate内部, 会让迭代器iter从参数first开始, 循环到last, 然后调用accumulate第四个参数(函数) op(init, *iter) (如果没传入第四个参数, 就会调用默认 val + *iter)

1.2.2 reduce

reduce用途与accumulate基本一致, 至于具体区别是什么, 据说是reduce函数中可以并行化来增加效率.

1.3 unique

该函数为在起始迭代器到终止迭代器中找出所有与前一个元素符合某种条件的元素(默认是"==")并放置与尾部,返回放置于尾部所有元素的起始位置:

1.4 查找

1.4.1 find

也是三个参数, 与find_if不同的是, 第三个参数需要传入的是找的值.

1.4.2 find_if

有三个参数: first, last, 条件; 如下测试代码:

void find_if_test() {vector<char> tVec;char ch[] = "hello world";TestUtils::getInstance()->getSequentialContainerByArr<char>(tVec, PARAM_ARRAY(ch));TestUtils::getInstance()->showContainerElements(tVec);auto iter = find_if(tVec.begin(),tVec.end(),[](auto element){return element == 'o';});if (iter == tVec.end()) {cout << "find o failed" << endl;} else {cout << "successfully find " << *iter << endl;}
}

结果:

1.4.3 adjacent_find

查找相邻重复元素, 如果查到了返回第一个元素迭代器, 查不到的话返回end();

如下测试代码:

void adjacent_find_test() {vector<int> tVec;int array[] = {2,3,5,8,7,1,5,6,2,5};TestUtils::getInstance()->getSequentialContainerByArr(tVec, PARAM_ARRAY(array));auto iter = adjacent_find(tVec.begin(), tVec.end());if (iter == tVec.end()) {cout << "find same element failed" << endl;} else {cout << "find same element " << *iter << endl;}sort(tVec.begin(), tVec.end(), less<int>());iter = adjacent_find(tVec.begin(), tVec.end());if (iter == tVec.end()) {cout << "find same element failed" << endl;} else {cout << "find same element " << *iter << endl;}auto riter = adjacent_find(tVec.rbegin(), tVec.rend());if (riter == tVec.rend()) {cout << "find same element failed" << endl;} else {cout << "find same element " << *riter << endl;}
}

结果:

1.4.4 binary_search

参数列表跟find一样, 但是返回值是true或者false. 这个查找法必须在有序的序列中才能使用, 效率比较高, 时间复杂度为o(log n).

如下测试函数:

void binary_search_test() {vector<int> tVec;for (int i = 0; i < 100000; i ++) {tVec.push_back(i);}double findStartTime = TestUtils::getInstance()->getNowMillisecond();auto iter = find(tVec.begin(), tVec.end(),38472);if (iter != tVec.end()) {cout << "successfully find " << *iter << endl;} else {cout << "find failed" << endl;}double findEndTime = TestUtils::getInstance()->getNowMillisecond();cout << "find cost " << findEndTime - findStartTime << "ms" << endl;double binary_searchStartTime = TestUtils::getInstance()->getNowMillisecond();bool ret = binary_search(tVec.begin(), tVec.end(),38472);if (ret) {cout << "successfully binary_search " << endl;} else {cout << "find failed" << endl;}double binary_searchEndTime = TestUtils::getInstance()->getNowMillisecond();cout << "binary_search cost " << binary_searchEndTime - binary_searchStartTime << "ms" << endl;
}

结果为:

参数中可以添加第四个参数, 就是序列排序的方法, 默认是从小到大排序的, 所以说当你传入的数组是降序排列且没有传入降序排列的参数, 那么就会找不到, 如下测试代码:

void binary_search_test_1() {vector<int> tVec;for (int i = 99999; i >= 0; i --) {tVec.push_back(i);}bool ret = binary_search(tVec.begin(), tVec.end(), 38472);if (ret) {cout << "successfully binary_search " << endl;} else {cout << "find failed" << endl;}
}

结果为:

当传入排序方式, 如下测试代码:

void binary_search_test_1() {vector<int> tVec;for (int i = 99999; i >= 0; i --) {tVec.push_back(i);}bool ret = binary_search(tVec.begin(), tVec.end(), 38472, greater<int>());if (ret) {cout << "successfully binary_search " << endl;} else {cout << "find failed" << endl;}
}

就会正常找到, 结果:

1.5 统计

1.5.1 count

同find类似, 三个参数是first, last, 统计值. 返回值是总数.

如下测试代码:

void count_test() {vector<int> tVec;for (int i = 99999; i >= 0; i --) {tVec.push_back(i);}for (int i = 0; i < 10; i ++) {tVec.push_back(10);}cout << count(tVec.begin(), tVec.end(), 10) << endl;
}

结果为:

 

1.5.2 count_if

同find_if类似, 也是三个参数, first, last, 条件.

如下测试代码:

void count_if_test() {vector<int> tVec;for (int i = 99999; i >= 0; i --) {tVec.push_back(i);}cout << count_if(tVec.begin(), tVec.end(), [](auto element){return element < 40000;}) << endl;
}

结果为:

1.6 random_shuffle

随机打乱序列算法, 只需传入first, last就可以, 如下测试代码:

void random_shuffle_test() {vector<int> tVec;TestUtils::getInstance()->getSequentialContainerByArr<int>(tVec);TestUtils::getInstance()->showContainerElements(tVec);random_shuffle(tVec.begin(),tVec.end());TestUtils::getInstance()->showContainerElements(tVec);
}

结果如下:

 

1.7 merge

将两个有序容器合并为一个有序容器, 如下测试代码:

void mergeTest1() {vector<int> tVec1;vector<int> tVec2;int array1[] = {0,2,4,6,8};int array2[] = {1,3,5,7,9};TestUtils::getInstance()->getSequentialContainerByArr(tVec1, PARAM_ARRAY(array1));TestUtils::getInstance()->getSequentialContainerByArr(tVec2, PARAM_ARRAY(array2));vector<int> tVec3;tVec3.resize(tVec1.size() + tVec2.size());merge(tVec1.begin(), tVec1.end(), tVec2.begin(), tVec2.end(), tVec3.begin());TestUtils::getInstance()->showContainerElements(tVec3);
}

 结果:

1.8 reverse

将序列反转, 需要提供起始迭代器和终止迭代器.测试代码如下:

void reverseTest() {vector<int> tVec;TestUtils::getInstance()->getSequentialContainerByArr<int>(tVec);TestUtils::getInstance()->showContainerElements(tVec);reverse(tVec.begin(), tVec.end());TestUtils::getInstance()->showContainerElements(tVec);
}

结果如下:

 

1.9 替换

1.9.1 replace

把一个容器中数据替换为另一个数据, 参数有四个, 起始迭代器, 终止迭代器, 需要被替换的值, 替换后的值.

如下测试代码:

void replaceTest() {vector<int> tVec;TestUtils::getInstance()->getSequentialContainerByArr<int>(tVec);TestUtils::getInstance()->showContainerElements(tVec);tVec.push_back(6);tVec.push_back(6);tVec.push_back(6);tVec.push_back(6);replace(tVec.begin(), tVec.end(), 6, 10);TestUtils::getInstance()->showContainerElements(tVec);
}

结果为:

1.9.2 replace_if

同find_if类似, 四个参数, 起始迭代器, 终止迭代器, 条件, 替换成的值, 如下测试代码:

void replace_ifTest() {vector<int> tVec;TestUtils::getInstance()->getSequentialContainerByArr<int>(tVec);TestUtils::getInstance()->showContainerElements(tVec);replace_if(tVec.begin(), tVec.end(), [](auto element){return element < 5;}, 10);TestUtils::getInstance()->showContainerElements(tVec);
}

结果为:

1.10 fill

如下测试代码:

void fillTest() {vector<int> tVec;tVec.resize(10);fill(tVec.begin(), tVec.end(), 10);TestUtils::getInstance()->showContainerElements(tVec);
}

结果:

1.11 集合算法

1.11.1 求容器交集 set_intersection

测试代码如下:

void set_intersectionTest() {int array1[] = {0,1,2,3,4,5,6,7,8,9};int array2[] = {8,9,10,11,12,13,14,15,16,17};vector<int> tVec1;TestUtils::getInstance()->getSequentialContainerByArr(tVec1, PARAM_ARRAY(array1));vector<int> tVec2;TestUtils::getInstance()->getSequentialContainerByArr(tVec2, PARAM_ARRAY(array2));vector<int> tVec3;tVec3.resize(min(tVec1.size(), tVec2.size()));auto iterEnd = set_intersection(tVec1.begin(), tVec1.end(), tVec2.begin(), tVec2.end(),tVec3.begin());TestUtils::getInstance()->showContainerElements(tVec3);tVec3.erase(iterEnd, tVec3.end());TestUtils::getInstance()->showContainerElements(tVec3);
}

结果为:

 

说明返回的是交集结束的迭代器, 剩下的都是0(因为调用的是resize). 接下来吧返回值迭代器到end() erase掉就可以了.

1.11.2 求容器并集 set_union

如下测试代码:

void set_unionTest() {int array1[] = {0,1,2,3,4,5,6,7,8,9};int array2[] = {8,9,10,11,12,13,14,15,16,17};vector<int> tVec1;TestUtils::getInstance()->getSequentialContainerByArr(tVec1, PARAM_ARRAY(array1));vector<int> tVec2;TestUtils::getInstance()->getSequentialContainerByArr(tVec2, PARAM_ARRAY(array2));vector<int> tVec3;tVec3.resize(tVec1.size() + tVec2.size());auto iterEnd = set_union(tVec1.begin(), tVec1.end(), tVec2.begin(), tVec2.end(),tVec3.begin());TestUtils::getInstance()->showContainerElements(tVec3);tVec3.erase(iterEnd, tVec3.end());TestUtils::getInstance()->showContainerElements(tVec3);
}

 结果为:

与交集同理.

1.11.3 求容器差集 set_difference

如下测试代码:

void set_differenceTest() {int array1[] = {0,1,2,3,4,5,6,7,8,9};int array2[] = {8,9,10,11,12,13,14,15,16,17};vector<int> tVec1;TestUtils::getInstance()->getSequentialContainerByArr(tVec1, PARAM_ARRAY(array1));vector<int> tVec2;TestUtils::getInstance()->getSequentialContainerByArr(tVec2, PARAM_ARRAY(array2));vector<int> tVec3;tVec3.resize(tVec1.size() + tVec2.size());auto iterEnd = set_difference(tVec1.begin(), tVec1.end(), tVec2.begin(), tVec2.end(),tVec3.begin());TestUtils::getInstance()->showContainerElements(tVec3);tVec3.erase(iterEnd, tVec3.end());TestUtils::getInstance()->showContainerElements(tVec3);vector<int> tVec4;tVec4.resize(tVec1.size() + tVec2.size());iterEnd = set_difference(tVec2.begin(), tVec2.end(), tVec1.begin(), tVec1.end(),tVec4.begin());TestUtils::getInstance()->showContainerElements(tVec4);tVec4.erase(iterEnd, tVec4.end());TestUtils::getInstance()->showContainerElements(tVec4);
}

结果为:

 

结果与刚开始想象的不一样, 之前以为是v1和v2的差集是两个集合中不相交的部分的集合, 但是输出的结果显示为set_difference的参数分别是:

  • 第一个集合的首
  • 第一个集合尾
  • 第二个集合的首
  • 第二个集合尾
  • 输出集合首

结果显示为输出的集合为第一个集合去掉了两个集合相交的部分即为第一个集合的差集.

2 STL提供的函数对象

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

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

相关文章

arma模型_GARCH模型应用:以国泰君安为例

1.下载国泰君安股票数据&#xff0c;计算对数收益率(1)首先安装包"quantmod"&#xff0c;这个包可以从雅虎财经的下载股票数据&#xff0c;具体包的解释见"【量化基础】R语言获取金融数据之quantmod包"。install.packages("quantmod")#安装包qua…

C++ STL 容器 string

1 string string内部含有一个char*字符串 2 string构造方式 无参构造 string str; 字符串构造 string str("abcd"); 拷贝构造n个相同字符 string str(10, k); //初始化为10个k 3 string赋值操作 可以有以下操作: void string_test() {string str1;str1 &qu…

小程序webview不全屏_小程序不在小(深度)

原标题&#xff1a;小程序不在小(深度)你问&#xff1a;“微信小程序适合哪些行业?”&#xff0c;回答是&#xff1a;“所有行业!”你可以想一下那些做过APP的公司&#xff0c;不管是任何行业的公司都可以拥有属于自己的APP&#xff0c;而从来不会有人问他们你们用的APP是否适…

leetcode 4 --- 寻找两个有序数组的中位数

1 题目 给定两个大小为 m 和 n 的正序&#xff08;从小到大&#xff09;数组 nums1 和 nums2。请你找出并返回这两个正序数组的中位数。 进阶&#xff1a;设计一个时间复杂度为 O(log (mn)) 的算法. 2 解法 这个题如果mn是偶数, 就是找到第(mn)/2以及第(mn)/2 1个数, 如果…

leetcode 142 --- linked-list-cycle-ii

1 题目&#xff1a; 对于一个给定的链表&#xff0c;返回环的入口节点&#xff0c;如果没有环&#xff0c;返回null 拓展&#xff1a; 你能给出不利用额外空间的解法么&#xff1f; 代码&#xff1a; class Solution { public:ListNode *detectCycle(ListNode *head) {} …

百度搜索引擎优化指南3.0_深圳网站搜索引擎排名优化电话,百度优化排名费用_华阳网络...

天津华阳在线科技有限公司为您详细解读深圳网站搜索引擎排名优化电话,百度优化排名费用的相关知识与详情&#xff1a;网站的主页标题是百度SEO的关键。你想要的主要关键词应该反映在标题中。如果标题写得好&#xff0c;百度很快就收录进去了。但要记住&#xff0c;有一点&#…

C++ STL 容器的一些总结 --- set(multiset)和map(multimap)

1 set和multiset 1.1 插入元素方式 set只能用insert插入数据. insert返回值是一个pair<iterator, bool>, 即插入数据的迭代器以及是否插入成功, multiset返回的只有迭代器, 因为不会插入失败. 1.2 删除 set只能用erase, 可以传迭代器或者是值. 1.3 注意事项 不允许…

苹果自带相册打马赛克_剪映app怎么给视频局部打马赛克

剪映app怎么给视频局部打马赛克呢&#xff1f;很多用户对此还不是很清楚&#xff0c;小编这里就给大家带来有关剪映app怎么给视频局部打马赛克的回答&#xff0c;希望能够对大家有所帮助。1、首先打开剪映app&#xff0c;进入首页后点击开始创作选项&#xff0c;2、这时选择需要…

excel表格如何转换成word表格_如何将excel转换成pdf?excel表格可以变成pdf文件吗?...

文字使用word&#xff0c;数据使用Excel&#xff0c;这应该是咱们日常生活中的一个规律了吧&#xff1f;不过不管是word文档还是Excel文档&#xff0c;都是可以被编辑修改的&#xff0c;那么我们怎么才能让它变得不能被编辑修改呢&#xff1f;小编这里还真有一个好方法&#xf…

python车牌识别系统开源代码_天津谁做车牌识别系统供应商,伸缩栅栏门_郑州荣锋科技有限公司...

首页 > 新闻中心发布时间&#xff1a;2020-11-13 22:54:57 导读&#xff1a;郑州荣锋科技有限公司为您提供天津谁做车牌识别系统供应商,伸缩栅栏门的相关知识与详情&#xff1a; (1)门处于关闭状态&#xff0c;控制器应骆动执行电机以佳速度曲线打开门;圆弧形自动门卷帘门机…

收发一体超声波测距离传感器模块_一文了解超声波液位计

为什么选择超声波液位计&#xff1f;因为&#xff0c;超声波液位计由声波的发射和接收之间的时间来计算传感器到被测物体的距离。无机械可动部分&#xff0c;可靠性高&#xff0c;安装简单、方便&#xff0c;属于非接触测量&#xff0c;且不受液体的粘度、密度等影响精度比较低…

什么牌子的平板电脑好_平板电脑什么牌子好?带你一探年度最佳平板的奥秘

阅读本文前&#xff0c;请您先点击上面的蓝色字体&#xff0c;再点击“关注”&#xff0c;这样您就可以免费收到最新内容了。每天都有分享&#xff0c;完全是免费订阅&#xff0c;请放心关注。声明&#xff1a;本文转载自网络&#xff0c;如有侵权&#xff0c;请在后台留言联系…

ieee754浮点数转换工具_关于JS浮点数运算不精确的原因和解决方案

背景之前在一个项目中&#xff0c;涉及到了金额&#xff0c;协议组定的标准是按照分的单位进行传递的&#xff0c;但是交互上&#xff0c;web页面中为了更友好的体验&#xff0c;是使用的元作为单位的&#xff0c;这个时候就需要转换一下单位本来是很简单的一个转化的需求&…

fir滤波器matlab实现_关于FIRamp;IIR系统的算法说明以及结果验证(1)

首先&#xff0c;做一个简短的开场白。本贴主要是一个关于信号处理方面的学习笔记。主要目的有三&#xff0c;作为研究笔记留存分享我个人的理解与专业人士进行意见交换另外由于楼主不是教课员&#xff0c;因此无法保证算法分析以及个人理解的完全正确性&#xff0c;若本人对知…

操作系统中的全局页面置换算法

1 全局页面置换算法 以上页面置换算法都是针对单一的应用程序的页面置换算法, 且有一个前提, 就是给单一应用程序分配的物理页帧数量是一定的. 现实中, 给一个应用程序分配的物理页帧数, 该程序产生的缺页中断也就越少, 而且程序运行过程中, 可能某些阶段对于内存的读写操作很…

怎么更新opengl.dll文件_安装累积更新丢文件似乎已成为惯例 KB4556799同样出现文件丢失问题...

从 Windows 10 Version 1903 版发布开始就经常出现用户升级版本或者安装累积更新导致个人文件丢失的问题。但是以前这种问题似乎并不算频繁&#xff0c;然而从今年开始微软发布的累积更新几乎都存在这样的问题让很多用户苦恼。而微软至今从未承认过安装累积更新会丢失用户的个人…

非全局页面置换算法

1 先进先出算法(FIFO) 1.1 基本思路: 选择在内存中驻留时间最长的页面并淘汰之. 具体来说, 系统维护着一个链表, 记录了所有位于内存当中的逻辑页面. 从链表的排列顺序来看, 链首页面的驻留时间最长, 链尾页面的驻留时间最短. 当发生一个缺页中断时, 把链首页面的淘汰出局, 并…

github打开前端样式丢失_工具资源系列之 github 上各式各样的小徽章从何而来?...

前言平时大家在在逛 github 时或多或少都看到过项目首页各式各样的小徽章,不知道你是否和我一样好奇这些小徽章都是哪来的呢?首先我们先来一睹为快目前前端开发的三大主流框架: var ,看一看他们的 github 项目首页有哪些小徽章吧!小结:前端三大框架的徽章均不相同,由此可见,这…

vs code ipynb文件_UE4引擎 源码的获取、安装,以及VS配置

1.首先我们需要注册一个Epic账户&#xff0c;网址如下http://api.unrealengine.com/CHN/GettingStarted/Installation/index.html#bookmark12.创建GitHub账户https://github.com/3.登录UE4社区点击个人进入到个人之后点击连接的账户&#xff0c;之后在下面填写我们GITHUB的昵称…

js bind 传参、_js中的面向对象(一)

面向对象要解决的问题提到面向对象&#xff0c;大家的第一反应就是封装、继承和多态。对其做如下解释&#xff1a;封装&#xff1a;影藏细节&#xff08;A对A——将多行代码取个名字或A对B——API调用合作&#xff09;继承&#xff1a;继承的意思就是同上跟上述一样&#xff0c…