zoukankan      html  css  js  c++  java
  • 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));

            

        }

  • 相关阅读:
    CSS 样式书写规范
    css等比例分割父级容器(完美三等分)
    右上角标的效果
    webstorm 激活破解方法大全
    ios开关按钮
    javascript功能封装
    Ajax 跨域
    javascript常用实例的实现与封装
    使用CSS完成元素居中的七种方法
    美化加载失败的图片
  • 原文地址:https://www.cnblogs.com/boydfd/p/4983155.html
Copyright © 2011-2022 走看看