【STL源码学习】STL算法学习之一

第一章:引子

STL包含的算法头文件有三个:<algorithm><numeric><functional>,其中最大最常用的是<algorithm>,今天学习的是<algorithm>包含的算法中的第一部分:非修改顺序操作算法。

接下来学习的算法基于C++11标准,较老的IDE会支持不全面或者部分算法不支持。

第二章:原型解析

如分类名称体现的信息,本节的所有函数都不会修改序列,并且原理上都是顺序遍历迭代器实现的。

all_of

函数原型:

template <class InputIterator,
class UnaryPredicate>

bool all_of (InputIterator
first, InputIterator last, UnaryPredicate pred);

函数作用:

比较迭代器区间的元素是否都满足pred的条件,就像名字一样,全部满足就返回true,否则返回false。

函数使用:

前闭后开区间[first,last),first和last为指向同一个容器对象的有效迭代器。

pred应当是一个单参且返回值为bool类型的函数,参数类型和迭代器的实例化类型一致。

使用示例:

bool foobool(int a)

{

if(10 == a)

return true;

return false;

}

void test_all_of()

{

bool bret = false;

vector<int>::iterator
itor1;

vector<int>::iterator
itor2;

vector<int> ivec(10,
10);

itor1 = ivec.begin();

itor2 = ivec.end();

bret = all_of(itor1, itor2,
foobool);

if(bret)

cout << "all_of return
true" << endl;

}

any_of

函数原型:

template <class InputIterator,
class UnaryPredicate>

bool any_of (InputIterator
first, InputIterator last, UnaryPredicate pred);

函数作用:

和all_of联系起来使用,如果有任何一个迭代器区间的元素满足要求就返回true,否则返回false。

none_of

函数原型:

template <class InputIterator,
class UnaryPredicate>

bool none_of (InputIterator
first, InputIterator last, UnaryPredicate pred);

函数作用:

和all_of、any_of联系起来使用,如果区间所有的元素都不满足pred的条件,就返回true,否则false。

for_each

函数原型:

template <class InputIterator,
class Function>

Function for_each
(InputIterator first, InputIterator last, Function fn);

函数作用:

对迭代区间的每一个元素都应用函数fn。

函数使用:

前闭后开区间[first,last),first和last为指向同一个容器对象的有效迭代器。

fun为接收单个参数的函数,返回值不限定,参数类型与迭代器实例类型保持一致。

find

函数原型:

template <class InputIterator,
class T>

InputIterator find
(InputIterator first, InputIterator last, const T& val);

函数作用:

迭代器区间[first,last)如果找到指定的元素就返回指向元素的迭代器,否则返回last。

函数使用:

前闭后开区间[first,last),first和last为指向同一个容器对象的有效迭代器。

find_if

函数原型:

template <class InputIterator,
class UnaryPredicate>

InputIterator find_if
(InputIterator first, InputIterator last, UnaryPredicate pred);

函数作用:

迭代器区间[first,last),如果存在满足pred条件的元素就返回指向该元素的迭代器,否则返回last

函数使用:

前闭后开区间[first,last),first和last为指向同一个容器对象的有效迭代器。

pred应当是一个单参且返回值为bool类型的函数,参数类型和迭代器的实例化类型一致。

find_if_not

函数原型:

template <class InputIterator,
class UnaryPredicate>

InputIterator find_if_not
(InputIterator first, InputIterator last, UnaryPredicate pred);

函数作用:

迭代器区间[first,last),如果存在不满足pred条件的元素就返回指向该元素的迭代器,否则返回last。

函数使用:

同find_if

find_end

函数原型:

template <class
ForwardIterator1, class ForwardIterator2>

ForwardIterator1 find_end
(ForwardIterator1 first1, ForwardIterator1 last1,ForwardIterator2 first2,
ForwardIterator2 last2);

template <class
ForwardIterator1, class ForwardIterator2, class BinaryPredicate>

ForwardIterator1 find_end
(ForwardIterator1 first1, ForwardIterator1 last1,ForwardIterator2 first2,
ForwardIterator2 last2,BinaryPredicate pred);

函数作用:

如果第二组迭代器指向的元素被包含在第一组迭代器中,则返回第一组迭代器中最后一个包含的开始位置,否则返回last1.

好拗口啊,看函数示例好理解一些。

函数有两个重载版本,分别用==和pred进行相等判断。

函数使用:

void test_find_end()

{

int array1[] = {1, 2, 3, 4, 5, 1,
2, 3};

int array2[] = {1, 2, 3};

int* ret = NULL;

ret = find_end(array1, array1+8,
array2, array2+3);

if(ret != array1+8)

cout << "find array2 last
contained in array1, position is " << ret - array1 << endl;

}

find_first_of

函数原型:

template <class InputIterator,
class ForwardIterator>

ForwardIterator1
find_first_of (InputIterator first1, InputIterator last1, ForwardIterator
first2, ForwardIterator last2);

template <class InputIterator,
class ForwardIterator, class BinaryPredicate>

ForwardIterator1
find_first_of (InputIterator first1, InputIterator last1, ForwardIterator
first2, ForwardIterator last2,BinaryPredicate pred);

函数作用:

和find_end很类似的作用,返回第二个迭代器区间第一处被包含在第一个迭代器区间的开始位置,成功则返回不等于last1的迭代器,否则返回last1.

adjacent_find

函数原型:

template <class
ForwardIterator>

ForwardIterator
adjacent_find (ForwardIterator first, ForwardIterator last);

template <class ForwardIterator,
class BinaryPredicate>

ForwardIterator
adjacent_find (ForwardIterator first, ForwardIterator last, BinaryPredicate
pred);

函数作用:

查找迭代器区间两个相邻的相等元素,并返回指向第一个相邻元素的迭代器,否则返回last。

count

函数原型:

template <class InputIterator,
class T>

typename
iterator_traits<InputIterator>::difference_type

count (InputIterator
first, InputIterator last, const T& val);

函数作用:

返回迭代器区间值等于val的元素的数量。

count_if

函数原型:

template <class InputIterator,
class Predicate>

typename
iterator_traits<InputIterator>::difference_type

count_if
(InputIterator first, InputIterator last, UnaryPredicate pred);

函数作用:

返回迭代器区间令pred返回true的元素的数量

mismatch

函数原型:

template <class InputIterator1,
class InputIterator2>

pair<InputIterator1,
InputIterator2>

mismatch
(InputIterator1 first1, InputIterator1 last1,

InputIterator2 first2);

template <class InputIterator1,
class InputIterator2, class BinaryPredicate>

pair<InputIterator1,
InputIterator2>

mismatch
(InputIterator1 first1, InputIterator1 last1,

InputIterator2 first2, BinaryPredicate pred);

函数作用:

比较[first1,last1)区间的元素与first2指向的元素,并返回第一处差异的元素pair,是否一致的判定为pred或==,总感觉这个函数存在缺陷,我该如何界定first2何时结束?会不会访问越界,搞清楚之前不使用这个函数。

equal

函数原型:

template <class InputIterator1,
class InputIterator2>

bool equal (InputIterator1
first1, InputIterator1 last1,

InputIterator2 first2);

template <class InputIterator1,
class InputIterator2, class BinaryPredicate>

bool equal (InputIterator1
first1, InputIterator1 last1,

InputIterator2 first2, BinaryPredicate pred);

函数作用:

比较[first1,last1)区间的元素是否全部==(或满足pred)first2指向的区间,同样认为是一个危险的函数,first2的区间长度需要调用者确保是大于first1的区间,但危险程度要小于mismatch。

is_permutation

函数原型:

template <class
ForwardIterator1, class ForwardIterator2>

bool is_permutation
(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2
first2);

template <class
ForwardIterator1, class ForwardIterator2, class BinaryPredicate>

bool is_permutation
(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2,
BinaryPredicate pred);

函数作用:

内部调用了mismatch,将之打入冷宫吧。

search

函数原型:

template <class
ForwardIterator1, class ForwardIterator2>

ForwardIterator1 search
(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2,
ForwardIterator2 last2);

template <class
ForwardIterator1, class ForwardIterator2, class BinaryPredicate>

ForwardIterator1 search
(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2,
ForwardIterator2 last2, BinaryPredicate pred);

函数作用:

返回第二个迭代器区间的元素第一次被包含第一个迭代器区间的首元素的地址,换一种类比的方式来讲:正向查找子串第一次被包含的位置。

search_n

函数原型:

template <class ForwardIterator,
class Size, class T>

ForwardIterator search_n
(ForwardIterator first, ForwardIterator last, Size count, const T&
val);

template <class ForwardIterator,
class Size, class T, class BinaryPredicate>

ForwardIterator search_n (
ForwardIterator first, ForwardIterator last, Size count, const T& val,
BinaryPredicate pred );

函数作用:

search的一个分支,第二个迭代器区间替换为count个val元素,其他一样的。

第三张:小结

这部分的算法都支持STL的容器,也不仅支持容器,只要具有和迭代器一样的++、--、==、=、*等的类型,比如普通指针都是支持的。

时间: 2024-08-07 00:09:47

【STL源码学习】STL算法学习之一的相关文章

STL源码剖析——STL算法之find查找算法

前言 由于在前文的<STL算法剖析>中,源码剖析非常多,不方便学习,也不方便以后复习,这里把这些算法进行归类,对他们单独的源码剖析进行讲解.本文介绍的STL算法中的find.search查找算法.在STL源码中有关算法的函数大部分在本文介绍,包含findand find_if.adjacent_find.search.search_n.lower_bound. upper_bound. equal_range.binary_search.find_first_of.find_end相关算法,下

STL源码剖析——STL算法之merge合并算法

前言 由于在前文的<STL算法剖析>中,源码剖析非常多,不方便学习,也不方便以后复习,这里把这些算法进行归类,对他们单独的源码剖析进行讲解.本文介绍的STL算法中的merge合并算法.源码中介绍了函数merge.inplace_merge.并对这些函数的源码进行详细的剖析,并适当给出使用例子,具体详见下面源码剖析. merge合并算法源码剖析 // merge, with and without an explicitly supplied comparison function. //将两个

STL源码剖析——STL算法之remove删除算法

前言 由于在前文的<STL算法剖析>中,源码剖析非常多,不方便学习,也不方便以后复习,这里把这些算法进行归类,对他们单独的源码剖析进行讲解.本文介绍的STL算法中的remove删除算法,源码中介绍了函数remove.remove_copy.remove_if.remove_copy_if.unique.unique_copy.并对这些函数的源码进行详细的剖析,并适当给出使用例子,具体详见下面源码剖析. remove移除算法源码剖析 // remove, remove_if, remove_co

STL源码剖析——STL算法stl_algo.h

前言 在前面的博文中剖析了STL的数值算法.基本算法和set集合算法,本文剖析STL其他的算法,例如排序算法.合并算法.查找算法等等.在剖析的时候,会针对函数给出一些例子说明函数的使用.源码出自SGI STL中的<stl_algo.h>文件.注:本文的源码非常多,可能后续博文会对这些算法进行归类分析. STL算法剖析 #ifndef __SGI_STL_INTERNAL_ALGO_H #define __SGI_STL_INTERNAL_ALGO_H #include <stl_heap

STL源码剖析——基本算法stl_algobase.h

前言 在STL中,算法是经常被使用的,算法在整个STL中起到非常重要的作用.本节介绍的是一些基本算法,包含equal,fill,fill_n,iter_swap,lexicographical_compare,max,min,mismatch,swap,copy,copy_backward,copy_n.其中一个比较重要的算法就是copy,针对copy的剖析在源码中可以看到详细的注解.本文剖析的源码出自SGL STL中的<stl_algobase.h>文件. 基本算法剖析 #ifndef __

STL源码剖析——STL函数对象

前言 在STL中,函数对象也是比较重要的,有时候可以限定STL算法的行为,例如在前面介绍的<STL算法剖析>中,每个算法基本上都提供了两个操作版本,其中就用一个版本允许用户指定函数对象,这样可以根据用户的需要对算法进行操作.函数对象是一种具有函数特质的对象,所以可以作为算法的参数.本文介绍的函数对象比较简单,是基于一元或者二元操作结构的算术类函数对象.关系运算类函数对象.逻辑运算类函数对象.在定义函数对象时,为了使其具有函数行为,则必须重载operator()操作符.本文源码出自SGI STL

STL源码剖析——STL算法之sort排序算法

前言 由于在前文的<STL算法剖析>中,源码剖析非常多,不方便学习,也不方便以后复习,这里把这些算法进行归类,对他们单独的源码剖析进行讲解.本文介绍的STL算法中的sort排序算法,SGI STL中的排序算法不是简单的快速排序,而是交叉利用各种排序:堆排序.插入排序和快速排序:这样做的目的是提高效率,针对数据量比较大的采用快速排序,数据量比较小的可以采用堆排序或插入排序.注意:STL的sort排序算法的迭代器必须是随机访问迭代器. sort排序算法剖析 // Return a random n

C++ 《STL源码剖析》 deque 学习

Deque 简介 deque是“double—ended queue”的缩写,和vector一样都是STL的容器,deque 是双端数组,而 vector 是单端的. deque 在接口上和 vector 非常相似,在许多操作的地方可以直接替换. deque 可以随机存取元素(支持索引值直接存取,用[]操作符或at()方法,这个等下会详讲). deque 头部和尾部添加或移除元素都非常快速.但是在中部安插元素或移除元素比较费时. 使用时需要包含头文件 #include<deque> . Deq

C++ 《STL源码剖析》学习-vector

本文章是笔者学习<STL源码剖析>的学习笔记,记录的是笔者的个人理解,因为个人的水平有限,难免会有理解不当的地方,而且该书出版的时间比较久,难免会有些不一样.如有不当,欢迎指出. vector是c++中经常用到的数据结构,而且在面试时也会有提及,因此了解vector很重要. 一说到vector,我们就很容易想到另外一个与它十分相似的数据结构,关于它们之间显著的差别,我觉得是在于空间运用的灵活性上.数组是静态的,在声明的时候就要指明其具体的空间大小,而vector是动态的,随着元素的增加,它内部

STL源码剖析之组件

本篇文章开始,进行STL源码剖析的一些知识点,后续系列笔记全是参照<STL源码剖析>进行学习记录的 STL在现在的大部分项目中,实用性已经没有Boost库好了,毕竟STL中仅仅提供了一些容器供编码者实用,Boost库相对而言全面了许多,所以更适合做一些项目的开发.但STL源码中依然有很多我们值得学习,思考的地方,包括现在大部分面试,都会问及到STL的框架源码部分.所以决定将这本书其中重要的几个部分拉出来做个笔记,以加深记忆并和大神们探讨探讨. 先简单介绍一下STL中的大致组成部分,一张图就明了