在 STL 中,算法是一系列的函数模版。STL 提供了大概 70 个算法,由头文件 <algorithm>、<numeric>、<functional>组成。

  • 头文件 <algorithm>   是最大的一个,里面经常使用到的功能有:查找、排序、改动、移除、交换、合并等;
  • 头文件 <numeric>     较小,主要包含相关数学运算的函数模版,以及加法和乘法在序列上的一些操作;
  • 头文件 <functional>  中则定义了一些类模版,来声明函数对象;

算法的分类:

  • 算法按事实上现的功能可分为 8 类:查找、排序、数值计算、比較、集合、容器管理、统计、 堆操作。
  • 算法按对容器的影响可分为 4 类:非修正、修正、排序、数值计算;

非修正算法

非修正即不正确容器中元素做改动。是仅仅读操作。如:find()、count()、equal()、for_each()、search()等。详细例如以下:

  1. adjacent_find #查找同样的相邻元素 返回第一个元素的迭代器
  2. find #查找
  3. find_first_of
  4. find_end
  5. find_last_of
  6. count #统计同样元素的个数
  7. count_if
  8. mismatch #返回 pair<第一个序列的迭代器,第二个序列的迭代器> 表明第一处不相符合的位置
  9. equal #比較容器中的元素是否同样
  10. for_each #经常使用,遍历序列并对序列中每一个元素採用仿函数中定义的操作
  11. search #返回迭代器,第一次出现序列二或者某元素的位置
  12. search_n #前n次连续出现某元素或者符合条件的第一个位置

修正算法

修正算法即对容器中元素做改动,须要写操作。

如:copy()、remove()、reverse()、swap()、unique()等。详细例如以下:

  1. copy #复制元素到目的容器
  2. copy_backward #从后往前复制
  3. fill #用某元素填充容器
  4. fill_n
  5. generate #把仿函数产生的结果依次拷贝到容器中
  6. generate_n
  7. partition #以仿函数为标准,把容器分成前后两部分,前半部分是能使仿函数返回真的元素,后半返回假
  8. stable_partition
  9. random_shuffle #对容器中的元素进行随机排列
  10. remove #删除某一范围内的元素,注意:移除的元素被放到容器末尾,还是能够用迭代器遍历到,函数返回移除后容器的末尾
  11. remove_if
  12. erase #擦除区间内全部的元素
  13. replace #在规定区间内把某值换成新值
  14. replace_if
  15. replace_copy #把区间内元素拷贝到目的地而且把当中某些元素替换成新值
  16. replace_copy_if
  17. rotate #把 middle-end 的元素放到 first 的位置上
  18. rotate_copy
  19. swap #元素的交换
  20. swap_ranges
  21. transform #把元素依照仿函数中内容转换
  22. unique #保证相邻元素间没有同样的,能够加仿函数做为推断根据,返回最后一个位置的迭代器
  23. unique_copy

排序算法

排序须要移动元素,所以须要用到随机訪问迭代器 RandomAccessIterator,而且指定 [begin,end) 这个前闭后开区间,且可自定义比較函数做參数传入。

常见容器的排序

  • vector 和 deque。还有数组,支持随机存取。能够用 algorithm 中的排序。
  • list 容器是双向链表,不支持随机訪问迭代器,内置了一种稳定排序方法,用的是自底向上的归并排序;
  • map 和 set 底层是红黑树。本身就是有序存储;

经常使用的排序函数

  1. sort #对给定区间全部元素进行排序,用的是快排
  2. stable_sort #稳定排序,保证值相等的元素排序后相对位置不变。用归并排序实现
  3. partial_sort #部分排序,保证前n个值有序而且后面的值不在前n个值的范围内,但后面的值不保证有序,堆排序实现
  4. partial_sort_copy #对给定区间复制并排序
  5. nth_element #把第n个元素放到第n个位置上去。比它大的都在后。比它小的都在前,但各自都不保证有序
  6. is_sorted #推断一个区间是否已经排好序
  7. partition #使得符合某个条件的元素放在前面
  8. stable_partition #相对稳定的使得符合某个条件的元素放在前面

经常使用的比較函数

  1. less #小于(缺省比較函数)
  2. greater #大于
  3. equal_to #等于
  4. less_equal #小于等于
  5. greater_equal #大于等于

自己定义比較大小

使用时不能直接写入仿函数的名字,而是要写其重载的() 函数。如 less<int>()。以下是 stl 中的 less 的部分源代码:

  1. template <class _Tp>
  2. struct less : public binary_function<_Tp,_Tp,bool>
  3. {
  4. bool operator()(const _Tp& __x, const _Tp& __y) const { return __x < __y; }
  5. };

对于基本数据类型和 string 能够使用 stl 中现成的函数模版,对于自定义的类。能够通过自己写比較函数或重载 < 操作符来实现。当中,重载 < 运算符相当于间接的用到了内置的 less  。

小样例

  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4. using namespace std;
  5.  
  6. class Test {
  7. public:
  8. Test(int a):a(a){};
  9. int a;
  10. bool operator <(const Test &k) const {
  11. return a < k.a;
  12. }
  13. };
  14.  
  15. int main(){
  16. vector<Test> a;
  17. a.push_back(Test(2));
  18. a.push_back(Test(3));
  19. a.push_back(Test(1));
  20. vector<Test>::iterator iter;
  21. sort(a.begin(), a.end());
  22. for(iter = a.begin(); iter != a.end(); ++iter){
  23. cout<< iter->a <<" ";
  24. } // 输出排序后:1 2 3
  25. }

数值计算

数值计算函数

数值计算算法主要针对容器中元素的计算,如 accumulate()、inner_product()、partial_sum()、adjacent_difference()和一些推广的数值算法。

详细:

  1. accumulate #遍历求和,也能够用仿函数求其它数值
  2. inner_product #内积。对应位置相乘再相加
  3. partial_sum #部分元素之和,把结果放到后一容器中,后一容器的第n个元素师前一容器的前n个容器元素之和
  4. adjacent_difference #相邻元素之差,把结果放到后一容器中

小样例

  1. #include <iostream>
  2. #include <functional>
  3. #include <numeric>
  4. #include <vector>
  5. using namespace std;
  6. int main() {
  7. int a[3] = { 2, 2, 3 };
  8. int re = accumulate(a, a + 3, 0);
  9. cout << re << endl; // 7, 累加
  10. vector<int> b;
  11. b.push_back(2);
  12. b.push_back(2);
  13. b.push_back(3);
  14. int re1 = accumulate(b.begin(), b.end(), 0, plus<int>());
  15. cout << re1 << endl; // 7, 累加
  16. int re2 = accumulate(b.begin(), b.end(), 1, multiplies<int>());
  17. cout << re2; // 12, 累乘
  18. }

有序容器、堆、集合

  1. binary_search #二分法搜索,在有序容器中提高搜索速度
  2. lower_bound #返回第一次出现该元素的位置
  3. upper_bound #返回最后一次出现该元素的后一位置
  4. equal_range #返回pair<lower_bound,upper_bound>
  5. inplace_merge #将连贯有序序列合并
  6. merge #合并两个容器
  7. includes #推断某区间内全部的元素是否在还有一区间中
  8.  
  9. #堆操作
  10. push_heap
  11. pop_heap
  12. sort_heap
  13. make_heap
  14.  
  15. #集合操作
  16. set_intersection
  17. set_difference
  18. set_symmetric_difference
  19.  
  20. #最值
  21. min #最小
  22. max #最大
  23. min_element #最小位置的迭代器
  24. max_element #最大位置的迭代器
  25. lexicograplical_compare #范围内的字典序比較。前后序列的比較
  26. next_permutation prev_permutation #上一个/下一个全排列

【原文地址:http://blog.csdn.net/thisinnocence/article/details/39941603】

STL 笔记(五) 算法 algorithm的更多相关文章

  1. STL学习笔记(五) 算法

    条款30:确保目标区间足够大 条款31:了解各种与排序有关的选择 //使用unaryPred划分输入序列,使得unaryPred为真的元素放在序列开头 partition(beg, end, unar ...

  2. STL笔记(6)标准库:标准库中的排序算法

    STL笔记(6)标准库:标准库中的排序算法 标准库:标准库中的排序算法The Standard Librarian: Sorting in the Standard Library Matthew A ...

  3. 数据结构(DataStructure)与算法(Algorithm)、STL应用

    catalogue . 引论 . 数据结构的概念 . 逻辑结构实例 2.1 堆栈 2.2 队列 2.3 树形结构 二叉树 . 物理结构实例 3.1 链表 单向线性链表 单向循环链表 双向线性链表 双向 ...

  4. STL学习笔记--排序算法

    排序算法 C++ STL 的排序算法(Sorting algorithms)是一组将无序序列排列成有序序列的模板函数或与排序相关的模板函数,提供了排序.折半搜索.归并.集合操作.堆操作.最值求解.字典 ...

  5. STL笔记(5)条款49:学习破解有关STL的编译器诊断信息

    STL笔记(5)条款49:学习破解有关STL的编译器诊断信息 条款49:学习破解有关STL的编译器诊断信息 用一个特定的大小定义一个vector是完全合法的, vector<int> v( ...

  6. STL笔记(3) copy()之绝版应用

    STL笔记(3) copy()之绝版应用 我选用了一个稍稍复杂一点的例子,它的大致功能是:从标准输入设备(一般是键盘)读入一些整型数据,然后对它们进行排序,最终将结果输出到标准输出设备(一般是显示器屏 ...

  7. STL中的算法

    STL中的所有算法(70个) 参考自:http://www.cppblog.com/mzty/archive/2007/03/14/19819.htmlhttp://hi.baidu.com/ding ...

  8. STL笔记(4)关于erase,remove

    STL笔记(4)关于erase,remove 你要erase的元素很容易识别.它们是从区间的“新逻辑终点”开始持续到区间真的终点的原来区间的元素.要除去那些元素,你要做的所有事情就是用那两个迭代器调用 ...

  9. 深度学习word2vec笔记之算法篇

    深度学习word2vec笔记之算法篇 声明:  本文转自推酷中的一篇博文http://www.tuicool.com/articles/fmuyamf,若有错误望海涵 前言 在看word2vec的资料 ...

随机推荐

  1. Mac使用之常用快捷键

    正式工作了,公司配给了mac,很多命令跟windows有很大不同,为了自己更好的使用mac本,特此记录平时常用的快捷键命令. 1.复制.保存等:command+c/s等,与windows不同的是ctr ...

  2. Scala-基础-运算符

    import junit.framework.TestCase /** * 运算符 */ class Demo3 extends TestCase { def test_+ { var x = 10; ...

  3. sql剪切数据

    实际项目当中用到的案例,个人笔记. USE [CA-SM]GO/****** Object:  StoredProcedure [dbo].[PG_SM_AddSum]    Script Date: ...

  4. CF869C The Intriguing Obsession

    思路: 分别在两种不同颜色的岛屿群之间进行搭桥.因为相同颜色的岛屿之间不能有边,任意两个相同颜色的岛屿不能同时和另外一个不同颜色的岛屿都有边.实现: #include <bits/stdc++. ...

  5. Android开发——Snackbar使用详解

    http://blog.csdn.net/qq_19431333/article/details/52862348

  6. 安装mask-rcnn问题汇总

    1. I download file from https://github.com/waleedka/coco. Then I placed the file in Mask_RCNN-master ...

  7. docloud后台管理项目(开篇)

    最近朋友做app需要web做后台管理,所以花了一周时间做了这个项目. 废话不多说,开发环境是nginx+php5.3,使用thinkphp框架.是一个医疗器械数据统计的后台,业务功能很简单就是查看用户 ...

  8. KM算法(Kuhn-Munkres)

    算法理论基础: 可行顶点标号 用l(v)表示顶点v的标号,w(uv)表示边(u,v)的权,对于赋权二分图G=(X,Y),若对每条边e=xy,均有l(x)+l(y)>=w(xy),则称这个标号为G ...

  9. 迭代器,生成器(generator)和Promise的“微妙”关系

    需要Promise源码版的朋友:传送链接 本文主要讲述(iterator)和生成器*/yield之间的联系和各自的用法,以及生成器的高配版本aysnc/await的使用. 大纲: 迭代器(iterat ...

  10. IP地址、MAC地址、ARP地址解析协议

    互联网中一台主机要和另一台主机实现通信首先需要知道彼此在互联网中的位置,主机在互联网中的位置是通过ip地址标记的,当找到ip地址后,再通过端口号标识运行在主机中的进程从而实现通信. IP地址: IP地 ...