码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2015-03-30 09:36:07      阅读:153      评论:0      收藏:0      [点我收藏+]

标签:stl源码剖析   c++   stl   算法   笔记   

//---------------------------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));

        

    }

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

标签:stl源码剖析   c++   stl   算法   笔记   

原文地址:http://blog.csdn.net/boydfd/article/details/44729001

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!