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

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

时间:2015-03-28 23:18:52      阅读:439      评论:0      收藏:0      [点我收藏+]

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

//---------------------------15/03/27----------------------------



//算法

{

    /*

        质变算法:会改变操作对象之值

        所有的stl算法都作用在由迭代器[first,last)所标示出来的区间上。质变算法 就是

        运算过程会更改区间内的元素内容

        非质变算法:和质变算法相反

                                                                            */

    /*

        stl算法的一般形式

        1>所有的泛型算法的前两个参数都是一对迭代器,通常称为firstlast,用以标示算法的操作区间

        2>stl习惯采用前闭后开区间,写成[first,last),表示区间包含firstlast(不包含last)

        之间的所有元素。

     

    */

    

    

    //****************************数值算法*****************************

    //accumulate

    //把区间中的数都加到” init的副本中 最后返回init副本值

    template<class InputIterator, class T>

    T accumulate(InputIterator first, InputIterator last, T init)

    {

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

            init = init + *first;

        return init;

    }

    

    template<class InputIterator,class T, class BinaryOperation>

    T accumulate(InputIterator first, InputIterator last, T init,

                 BinaryOperation binary_op)

    {

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

            init = binary_op(init, *first);

        return init;

    }

    

    //adjacent_difference

    //把区间中的数都  “减去前一个数 并把结果输出到一个迭代器中

    template<class InputIterator, class OutputIterator>

    OutputIterator adjacent_difference(InputIterator first, InputIterator last,

                                       OutputIterator result)

    {

        if(first == last) return result;

        *result = *first;

        return __adjacent_difference(first, last, result, value_type(first));

    }

    

    template<class InputIterator, class OutputIterator,class T>

    OutputIterator __adjacent_difference(InputIterator first, InputIterator last,

                                         OutputIterator result, T*)

    {

        T value = *first;

        while(++first != last)

        {

            T tmp = *first;

            *++result = tmp - value;

            value = tmp;

        }

        return ++result;

    }

    

    template<class InputIterator, class OutputIterator, class BinaryOperation>

    OutputIterator adjacent_difference(InputIterator first, InputIterator last,

                                       OutputIterator result,

                                       BinaryOperation binary_op)

    {

        if(first == last) return result;

        *result = *first;

        return __adjacent_difference(first, last, result, value_type(first),

                                     binary_op);

        

    }

    

    template<class InputIterator, class OutputIterator,class T>

    OutputIterator __adjacent_difference(InputIterator first, InputIterator last,

                                         OutputIterator result, T*,

                                         BinaryOperation binary_op)

    {

        T value = *first;

        while(++first != last)

        {

            T tmp = *first;

            *++result = binary_op(tmp,value);

            value = tmp;

        }

        return ++result;

    }

    

    

    //inner_product

    //把两个区间中的数做内积并都加到” init的副本中并最后返回这副本

    template<class InputIterator1, class InputIterator2,class T>

    T inner_product(InputIterator1 first1, InputIterator last1,

                    InputIterator2 first2, T init)

    {

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

            init = init + (*first1 * *first2);

        return init;

    }

    

    template<class InputIterator1, class InputIterator2,class T,

            class BinaryOperation1, class BinaryOperation2>

    T inner_product(InputIterator1 first1, InputIterator last1,

                    InputIterator2 first2, T init, BinaryOperation1 binary_op1,

                    BinaryOperation2 binary_op2)

    {

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

            init = binary_op1(init, binary_op2(*first1, *first2));

        return init;

    }

    

    //partial_sum

    //把区间中的数都 起来。 每加一次就输出一次到 指定迭代器。

    template<class InputIterator, class OutputIterator>

    OutputIterator partial_sum(InputIterator first, InputIterator last,

                                       OutputIterator result)

    {

        if(first == last) return result;

        *result = *first;

        return __partial_sum(first, last, result, value_type(first));

    }

    

    template<class InputIterator, class OutputIterator,class T>

    OutputIterator __partial_sum(InputIterator first, InputIterator last,

                                         OutputIterator result, T*)

    {

        T value = *first;

        while(++first != last)

        {

            value = value + *first;

            *++result = value;

        }

        return ++result;

    }

    

    

    template<class InputIterator, class OutputIterator, class BinaryOperation>

    OutputIterator partial_sum(InputIterator first, InputIterator last,

                               OutputIterator result, BinaryOperation binary_op)

    {

        if(first == last) return result;

        *result = *first;

        return __partial_sum(first, last, result, value_type(first), binary_op);

    }

    

    template<class InputIterator, class OutputIterator,class T>

    OutputIterator __partial_sum(InputIterator first, InputIterator last,

                                 OutputIterator result, T*,

                                 BinaryOperation binary_op)

    {

        T value = *first;

        while(++first != last)

        {

            value = binary_op(value, *first);

            *++result = value;

        }

        return ++result;

    }

    

    //power

    

    template<class T, class Interger>

    inline T power(T x, Interger n)

    {

        return power(x,n,multiplies<T>());

    }

    

    template<class T, class Interger, class MonoidOperation>

    T power(T x, Interger n, MonoidOperation op)

    {

        if(n == 0)

            return identity_element(op);

        else

        {

            //确定 xm 值, 为了不重复计算,看n是否能被 xm 整除,通过移位便可确定

            while ((n & 1) == 0)

            {

                n >>= 1;

                x = op(x, x);

            }

            //也是为了不重复计算,把xn次拆分成2^m+2^(m-1)+2^(m-2)+...+1

            //先算出1次,再算出2次,再算出4次。只要对应位置上有数,加进reslt就行,

            //没有数则不加。

            T result = x;

            n >>= 1;

            while (n != 0)

            {

                x = op(x, x);

                if((n & 1) != 0)

                    result = op(result, x);

                n >>= 1;

            }

            return result;

        }

    }

    

    // itoa

    //在一个区间中依次写入value value+1...

    template<class ForwardIterator, class T>

    void itoa(ForwardIterator first, ForwardIterator last, T value)

    {

        while(first != last)

            *first++ = value++;

    }

    //****************************数值算法*****************************

    

    //****************************基本算法*****************************

    

    //equal

    

    template<class InputIterator1, class InputIterator2>

    inline bool equal(InputIterator1 first1, InputIterator1 last1,

                      InputIterator2 first2)

    {

        for(; first != last1; ++first1,++first2)

            if(*first1 != *first2)

                return false;

        return true;

            

    }

    

    

    template<class InputIterator1, class InputIterator2,

            class BinaryPredicate>

    inline bool equal(InputIterator1 first1, InputIterator1 last1,

                      InputIterator2 first2, BinaryPredicate binary_op)

    {

        for(; first != last1; ++first1,++first2)

            if(!binary_op(*first1,*first2))

                return false;

        return true;

        

    }

    

    //fill

    template<class ForwardIterator, class T>

    void fill(ForwardIterator first, ForwardIterator last, const T& value)

    {

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

            *first = value;

    }

    

    //fill_n

    //这里少了比较 first不需要和last比较来确定中止条件 所以只需要一个output迭代器

    template<class OutputIterator, class Size, class T>

    OutputIterator fill_n(OutputIterator first, Size n, const T& value)

    {

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

            *first = value;

        return first;

    }

    

    //iter_swap

    template<class ForwardIterator1, class ForwardIterator2>

    inline void iter_swap(ForwardIterator1 a, ForwardIterator2 b)

    {

        __iter_swap(a, b, value_type(a));

    }

    

    template<class ForwardIterator1, class ForwardIterator2, class T>

    inline void __iter_swap(ForwardIterator1 a, ForwardIterator2 b, T*)

    {

        T tmp = *a;

        *a = *b;

        *b = tmp;

    }

    

    //lexicographical_compare 按字典比较

    template<class InputIterator1, class InputIterator2>

    bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1,

                                 InputIterator2 first2, InputIterator2 last2)

    {

        for(; first1 != last1 && first2 != last2; ++first1, ++first2)

        {

            if(*first1 < *first2)

                return true;

            if(*first2 < *first1)

                return false

        }

        return first1 == last1 && first2 != last2;

    }

    

    template<class InputIterator1, class InputIterator2, class Compare>

    bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1,

                                 InputIterator2 first2, InputIterator2 last2,

                                 Compare comp)

    {

        for(; first1 != last1 && first2 != last2; ++first1, ++first2)

        {

            if(comp(*first1, *first2))

                return true;

            if(comp(*first2, *first1))

                return false

        }

        return first1 == last1 && first2 != last2;

    }

    

    inline bool

    lexicographical_compare(const unsigned char* first1,

                            const unsigned char* last1,

                            const unsigned char* first2,

                            const unsigned char* last2)

    {

        const size_t len1 = last1 - first1;

        const size_t len2 = last2 - first2;

        const int result = memcmp(first1, first2, min(len1, len2));

        return result != 0 ? result < 0 : len1 < len2;

    }

    

    //max两者比较返回大值

    template<class T>

    inline const T& max(const T& a, const T& b)

    {

        return a < b ? b : a;

    }

    

    template<class T, class Compare>

    inline const T& max(const T& a, const T& b, Compare comp)

    {

        return comp(a, b) ? b : a;

    }

    

    //min两者比较返回小值

    

    template<class T>

    inline const T& min(const T& a, const T& b)

    {

        return b < a ? b : a;

    }

    

    template<class T, class Compare>

    inline const T& min(const T& a, const T& b, Compare comp)

    {

        return comp(b,a) ? b : a;

    }

    

    //mismatch 找到第一个不匹配点

    template<class InputIterator1, class InputIterator2>

    pair<InputIterator1, InputIterator2> mismatch(

                                        InputIterator1 first1,

                                        InputIterator1 last1,

                                        InputIterator2 first2)

    {

        while (first != last1 && *first1 == *first2)

        {

            ++first1;

            ++first2;

        }

        return pair<InputIterator1, InputIterator2>(first1, first2);

    }

    

    template<class InputIterator1, class InputIterator2,

            class BinaryPredicate>

    pair<InputIterator1, InputIterator2> mismatch(

                                    InputIterator1 first1,

                                    InputIterator1 last1,

                                    InputIterator2 first2,

                                    BinaryPredicate binary_pred)

    {

        while (first1 != last1 && binary_pred(*first1, *first2))

        {

            ++first1;

            ++first2;

        }

        return pair<InputIterator1, InputIterator2>(first1, first2);

    }

    

    //swap

    template<class T>

    inline void swap(T& a, T& b)

    {

        T tmp = a;

        a = b;

        b = tmp;

    }

    

    

    //copy这个函数为了强化效率下了血本

    

    //正常版本走这边

    template<class InputIterator, class OutputIterator>

    inline OutputIterator copy(InputIterator first, InputIterator last,

                               OutputIterator result)

    {

        return __copy_dispatch<InputIterator,OutputIterator>()

                                (first, last, result);

    }

    

    //char* wchar_t* 走这边

    inline char* copy(const char* first, const char* last, char* result)

    {

        memmove(result, first, last - first);

        return result + (last - first);

    }

    

    inline wchar_t* copy(const wchar_t* first, const wchar_t* last,

                         const wchar_t* result)

    {

        memmove(result, first, sizeof(wchar_t) * (last - first));

        return result + (last - first);

    }

    

    

    //准备一个仿函数,用来再次特化,用仿函数可以根据传入的InputIterator来特化

    //正常版本走这边

    template<class InputIterator, char OutputIterator>

    struct __copy_dispatch

    {

        OutputIterator operator()(InputIterator first, InputIterator last,

                                  OutputIterator result)

        {

            //传入一个迭代器标签,区分是否是随机迭代器

            return __copy(first, last, result, iterator_category(first));

        }

    };

    

    //指针走这边

    template<class T>

    struct __copy_dispatch<T*, T*>

    {

        T* operator()(T* first, T* last, T* result)

        {

            //判断 是否 没有 assignment_operator重载操作

            typedef typename __type_traits<T>::has_trivial_assignment_operator t;

            return __copy_t(first, last, result, t());

        }

    };

    

    //const指针走这边

    template<class T>

    struct __copy_dispatch<const T*, T*>

    {

      T* operator()(const T* first, const T* last, T* result)

        {

            typedef typename __type_traits<T>:: has_trivial_assignment_operator t;

            return __copy_t(first, last, result, t());

        }

    };

    

    //input是基类,不管forward 还是bidi迭代器都走这边

    template<class InputIterator, class OutputIterator>

    inline OutputIterator __copy(InputIterator first, InputIterator last,

                                 OutputIterator result, input_iterator_tag)

    {

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

            *result = *first;

        return result;

    }

    

    //随机迭代器走这边

    template<class RandomAccessIterator, class OutputIterator>

    inline OutputIterator

    __copy(RandomAccessIterator first, RandomAccessIterator last,

           OutputIterator result, random_access_iterator_tag)

    {

        return __copy_d(first, last, result, distance_type(first));

    }

    

    //直接算出区间大小,根据大小来循环 不需要判断迭代是否相等,可以有效提升速度

    template<class RandomAccessIterator, class OutputIterator, class Distance>

    inline OutputIterator

    __copy_d(RandomAccessIterator first, RandomAccessIterator last,

             OutputIterator result, Distance*)

    {

        for(Distance n = last - first; n > 0; --n, ++result, ++first )

            *result = *first;

        return result;

    }

    

    

    // 没有assignment_operator重载操作的话 就走这。直接复制内存

    template<class T>

    inline T* __copy_t(const T* first, const T* last, T* result,

                       __true_type)

    {

        memmove(result, first, sizeof(T) * (last - first));

        return result + (last - first);

    }

    

    //不是 没有assignment_operator重载操作(也就是有重载) 走这边,调用随机迭代器的copy方法

    template<class T>

    inline T* __copy_t(const T* first, const T* last, T* result,

                        __false_type)

    {

        return __copy_d(first, last, result, (ptrdiff_t*) 0);

    }


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

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

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

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