您的位置:首页 > 其它

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

2015-03-29 18:26 381 查看
//---------------------------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));

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: