stl源码剖析 详细学习笔记 算法(2)

//---------------------------15/03/29----------------------------

//****************************set相关算法*****************************

/*

1>set相关算法一共有4种:并集(union),交集(intersection),差集(difference),

对称差集(symmetric difference)。

2>set相关算法只接受set/multiset。

3>每个算法都是根据 “<”(可以自行定义)
来确定大小 以及是否相等。

4>这四个算法都是稳定算法,执行后元素的相对顺序不会改变

*/

//set_union

//并集就是除了一样的不加
其它的通通塞到Output迭代器中去,所以比较大小,把

//小的都塞进去,碰到相等的,塞一个进去。最后可能两个迭代器中有一个还有剩余,

//就把剩余的都拷贝到
输出区间

template<class InputIterator1,
class InputIterator2,
class OutputIterator>

OutputIterator set_union(InputIterator first1, InputIterator last1,

InputIterator first2, InputIterator last2,

OutputIterator result)

{

while (first1 != last1 && first2 != last)

{

if (*first1 < *first2)
//自定义版本是这样的: if(comp(*first1, *first2))

{

*result = *first1;

++first1;

}

else
if(*first2 < *first1)//自定义版本:  if(comp(*first2, *first1))

{

*result = *first2;

++first2;

}

else

{

*result = *first1;

++first1;

++first2;

}

++result;

}

return copy(first2, last2, copy(first1, last1, result));

}

//set_intersection

//交集么只要取相等的元素,遇到不相等情况的,只要把小的那自加即可。最后就算那个区间有多也可以不管了。

template<class InputIterator1,
class InputIterator2,
class OutputIterator>

OutputIterator set_intersection(InputIterator first1, InputIterator last1,

InputIterator first2, InputIterator last2,

OutputIterator result)

{

while (first1 != last1 && first2 != last2)

{

if(*first1 < *first2)

++first1;

else if(*first2 < *first1)

++first2;

else

{

*result = *first1;

++first1;

++first2;

++result;

}

}

return result;

}

//set_difference

//差集则只要考虑区间1中有的,区间2中没有的,1中小于2的元素可以输出,碰到相等的就让

//两个区间的都自加,2中小于1的并没有意义,只需让2自加即可,最后1中有剩余的输出,不用考虑2剩余的情况

template<class InputIterator1,
class InputIterator2,
class OutputIterator>

OutputIterator set_difference(InputIterator first1, InputIterator last1,

InputIterator first2, InputIterator last2,

OutputIterator result)

{

while (first1 != last1 && first2 != last2)

{

if(*first1 < *first2)

{

*result = *first;

++first1;

++result;

}

else if(*first2 < *first1)

++first2;

else

{

++first1;

++first2;

}

}

return copy(first, last1, result);

}

//set_symmetric_difference

//对称差集,只有相等的情况不输出,所以碰到相等的
两个区间都自加,剩下情况的都输出。

//最后会有一个区间有多,也要都输出

template<class InputIterator1,
class InputIterator2,
class OutputIterator>

OutputIterator set_difference(InputIterator first1, InputIterator last1,

InputIterator first2, InputIterator last2,

OutputIterator result)

{

while (first1 != last1 && first2 != last2)

{

if(*first1 < *first2)

{

*result = *first1;

++first1;

++result;

}

else if(*first2 < *first1)

{

*result = *first2

++first2;

++result;

}

else

{

++first1;

++first2;

}

}

return copy(first2, last2, copy(first1, last1, result));

}

//****************************set相关算法*****************************

//****************************其它算法*****************************

//adjacent_find

//找到第一组
满足条件(默认是 ==)的
相邻元素

template<class ForwardIterator>

ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last)

{

if (first == last)

return last;

ForwardIterator next = first;

while (++next != last)

{

if(*first == *next)    
//自己定义版本 if(binary_pred(*first, *next))

return first;

first = next;

}

return last;

}

//count

//找到与传入的value相等的元素的个数

template<class InputIterator,
class T>

typename iterator_traits<InputIterator>::difference_type

count(InputIterator first, InputIterator last,
const T& value)

{

typename iterator_traits<InputIterator>::difference_type n =0;

for(; first != last; ++first)

if(*first == value)    
//count_if版本 if( pred(*first))

++n;

return n;

}

//find

//找到第一个符合条件的元素

template<class InputIterator,
class T>

InputIterator find(InputIterator first, InputIterator last,

const T& value)

{

//find_if版本 while(first != last && !pred(*first))

while(first != last && *first != value)

++first;

return first;

}

//find_end

//找到区间1中最后一组
和区间2 相同的元素

//如果可以从队尾开始搜索可以快很多,所以分两种情况,可以后退的迭代器,不能后退的迭代器

template<class ForwardIterator1,
class ForwardIterator2>

inline ForwardIterator1

find_end(ForwardIterator1 first1, ForwardIterator1 last1,

ForwardIterator2 first2, ForwardIterator2 last2)

{

typedef typename iterator_traits<ForwardIterator1>::iterator_category

category1;

typedef typename iterator_traits<ForwardIterator2>::iterator_category

category2;

return __find_end(first1, last1, first2, last2, category1(), category2());

}

template<class ForwardIterator1,
class ForwardIterator2>

ForwardIterator1 __find_end(ForwardIterator1 first1, ForwardIterator1 last1,

ForwardIterator2 first2, ForwardIterator2 last2,

forward_iterator_tag, forward_iterator_tag)

{

if(first2 == last2)

return last1;

else

{

ForwardIterator1 result = last1;

while (1)

{

//先搜索下一组,再把下一组赋给result 
就和单链表删除节点一样,要删除下一个节点,

//我们要预留上一个节点,这里是要先找到
下一个不符合的情况 我们才知道这是最后一个

ForwardIterator1 new_result = search(first1, last1, first2, last2);

if(new_result == last1)

return result;

else

{

result = new_result;

first1 = new_result;

++first;

}

}

}

}

//双向迭代器走这边

template<class BidirectionalIterator1,
class BidirectionalIterator2>

BidirectionalIterator1

__find_end(BidirectionalIterator1 first1, BidirectionalIterator1 last1,

BidirectionalIterator2 first2, BidirectionalIterator2 last2,

bidirectional_iterator_tag, bidirectional_iterator_tag)

{

typedef reverse_iterator<BidirectionalIterator1> reviter1;

typedef reverse_iterator<BidirectionalIterator2> reviter2;

//先确定end位置

reviter1 rlast1(first1);

reviter2 rlast2(first2);

//找到第一组就可以了

reviter1 rresult = search(reviter1(last1), rlast1,

reviter2(last2), rlast2);

if(rresult == rlast1)

return last1;      
//没找到

else

{

//修改位置, base()成员函数可以取得真实位置,因为反向迭代器有两个位置,

//一个是真实位置,一个是他 “下一个”位置
他的”下一个“其实是正向迭代器的上一个

//1 2 3
此时反向迭代器指向3 operator*() 取到的是2 base()取到的是 3

//下面的操作是为了使result == end

BidirectionalIterator1 result = rresult.base();

//减去距离,就可以使result变成first

advance(result, -distance(first2, last2));

return result;

}

}

//find_first_of

//在区间1中找到
第一个 与区间2中
任意元素匹配 的位置

template<class InputIterator,
class ForwardIterator>

InputIterator find_first_of(InputIterator first1, InputIterator last1,

ForwardIterator first2, ForwardIterator last2)

{

for(; first1 != last1; ++first1)

for(ForwardIterator iter = first2; iter != last2; ++iter)

if(*first1 == *iter)       
//自定义版本 if(comp(*first, *last))

return first;

return last1;

}

//for_each

//对每个元素调用仿函数f

template<class InputIterator,
class Function>

Function for_each(InputIterator first, InputIterator last, Function f)

{

for(; first != last; ++first)

f(*first);

return f;

}

//generate

//把仿函数的返回值填充区间。相当于:  auto rel=gen(); fill(first, last, rel);

template<class ForwardIterator,
class Generator>

void generate(ForwardIterator first, ForwardIterator last, Generator gen)

{

for(; first != last; ++first)

*first = gen();

}

//填充n个 gen()

template<class OutputIterator,class Size,
class Generator>

OutputIterator generate_n(OutputIterator first, Size n, Generator gen)

{

for(; n > 0; --n, ++first)

*first = gen();

return first;

}

//includes
应用于有序的区间

//依次找,只要区间1的元素
小于等于 区间二就继续下去
一旦区间2中的元素小于区间1的

//说明这个数
在区间1中
就找不到和他相等的数了,就可以返回false了

template<class InputIterator1,
class InputIterator2>

bool includes(InputIterator1 first1, InputIterator1 last1,

InputIterator2 first2, InputIterator2 last2)

{

while (first1 != last1 && first2 != last2)

{

if(*first2 < *first1)  
//自定义版本:if(comp(*first2, *first1))

return false;

else
if(*first1 < *first2)
//自定义版本:if(comp(*first1, *first2))

++first1;

else

++first1, ++first2;

}

return first2 == last2;

}

//max_element

template<class ForwardIterator>

ForwardIterator max_element(ForwardIterator first, ForwardIterator last)

{

if(first == last)

return first;

ForwardIterator result = first;

while(++first != last)

if(*result < *first)       
//自定义版本: if(comp(*result, *first))

result = first;

return result;

}

//merge
要求有序

template<class InputIterator1,
class InputIterator2,
class OutputIterator>

OutputIterator merge(InputIterator1 first1, InputIterator1 last1,

InputIterator2 first2, InputIterator2 last2,

OutputIterator result)

{

while (first1 != last1 && first2 != last2)

{

if(*first2 < *first1)  
//自定义版本: if(comp(*first2, *first1))

{

*result = *first2;

++first2;

}

else

{

*result = *first1;

++first1;

}

++result;

}

return copy(first2, last2, copy(first1, last1, result));

}

时间: 2024-11-09 09:45:51

stl源码剖析 详细学习笔记 算法(2)的相关文章

stl源码剖析 详细学习笔记 算法总览

//****************************基本算法***************************** /* stl算法总览,不在stl标准规格的sgi专属算法,都以 *加以标记 算法名称              算法用途         质变                   所在文件 accumulate          元素累计            否                   <stl_numeric.h> adjacent_differenc

stl源码剖析 详细学习笔记 算法(1)

//---------------------------15/03/27---------------------------- //算法 { /* 质变算法:会改变操作对象之值 所有的stl算法都作用在由迭代器[first,last)所标示出来的区间上.质变算法 就是 运算过程会更改区间内的元素内容 非质变算法:和质变算法相反 */ /* stl算法的一般形式 1>所有的泛型算法的前两个参数都是一对迭代器,通常称为first和last,用以标示算法的操作区间 2>stl习惯采用前闭后开区间

stl源码剖析 详细学习笔记 算法(4)

//---------------------------15/03/31---------------------------- //lower_bound(要求有序) template<class ForwardIterator, class T> inline ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, const T& value) { return __lower_bound

stl源码剖析 详细学习笔记 算法(5)

//---------------------------15/04/01---------------------------- //inplace_merge(要求有序) template<class BidirectionalIterator> inline void inplace_merge(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last) { if(first

stl源码剖析 详细学习笔记 算法(3)

//---------------------------15/03/30---------------------------- //min_element template<class ForwardIterator> ForwardIterator min_element(ForwardIterator first, ForwardIterator last) { if(first == last) return first; ForwardIterator result = first

stl源码剖析 详细学习笔记 空间配置器

//---------------------------15/04/05---------------------------- /* 空间配置器概述: 1:new操作包含两个阶段操作 1>调用::operator new配置内存(底层使用malloc来申请内存). 2>调用函数的构造函数,构造对象内容. delte和new一样,先调用析构函数,再调用::operator delete释放内存. 2:为了效率,stl把两个阶段分开来. 1>内存配置操作: alloc::allocate

stl源码剖析 详细学习笔记 仿函数

//---------------------------15/04/01---------------------------- //仿函数是为了算法而诞生的,可以作为算法的一个参数,来自定义各种操作,比如比大小,返回bool值,对元素进行操作等 //虽然这些函数也能实现,但是如果配合配接器(adapter)可以产生更灵活的变化. //为了使对象像函数一样,就必须重载operator() //unary_function template<class Arg, class Result> s

stl源码剖析 详细学习笔记 配接器

//---------------------------15/04/03---------------------------- /* 配接器概述: 1:adapter是一种设计模式:将一个class的接口转换为另一个class的接口,使得原本因接口不兼容而 不能合作的classes可以一起工作. 2:改变仿函数接口的,称为function adapter,改变容器接口的,称为container adapter, 改变迭代器接口的,称为iterator adapter. 3:container

《STL源码剖析》学习笔记-第6章(一) set相关算法

STL中定义的set要求元素不得重复且已经排序.而set算法要求的都是有序区间(输出也是有序的),但元素可以重复出现. STL提供了4个set相关的算法,分别是并集(union).交集(intersection).差集(difference)和对称差集(symmetric difference),这4个算法接受的set必须是有序区间,都至少接受4个参数,分别表示两个set区间.一般而言,set算法前4个参数分别表示两个区间,第五个参数表示存放结果的区间的起始位置. 1.set_union 求两个