zoukankan      html  css  js  c++  java
  • 基本算法(equal,fill,iter_swap,generate,generate_n,copy,mismatch)

    euqal

      比较两个序列是否相等,相等返回true,不相等返回false

    template <class _InputIter1, class _InputIter2>//版本1
    inline bool equal(_InputIter1 __first1, _InputIter1 __last1,
                      _InputIter2 __first2) {
      for ( ; __first1 != __last1; ++__first1, ++__first2)//遍历区间[first,last)元素
        if (*__first1 != *__first2)//只有有一个不相等返回false
          return false;
      return true;
    }
     
    template <class _InputIter1, class _InputIter2, class _BinaryPredicate>//版本2
    inline bool equal(_InputIter1 __first1, _InputIter1 __last1,
                      _InputIter2 __first2, _BinaryPredicate __binary_pred) {
      for ( ; __first1 != __last1; ++__first1, ++__first2)
        if (!__binary_pred(*__first1, *__first2))//两个元素执行二元操作符
          return false;
      return true;
    }

    fill

      将value值填充整个区间,不能为OutputIterator,因为fill会用到first和last,outputIterator无法做相等的测试

    template <class ForwardIterator, class T>
    void fill( ForwardIterator first, ForwardIterator last,const T& value);

    fill_n

      会将数值value填充[first,first+n),返回值为first+n,可以用outputIterator

    template <class OutputIterator,class size,class T>
    OutputIterator fill_n( OutputIterator first, OutputIterator last,size n,const T& value);

    iter_swap

      将两个迭代器所指对象互换

    template <class _ForwardIter1, class _ForwardIter2, class _Tp>
    inline void __iter_swap(_ForwardIter1 __a, _ForwardIter2 __b, _Tp*) {
        _Tp __tmp = *__a;
        *__a = *__b;
        *__b = __tmp;
    }
    
    template <class _ForwardIter1, class _ForwardIter2>
    inline void iter_swap(_ForwardIter1 __a, _ForwardIter2 __b) {
        __iter_swap(__a, __b, __VALUE_TYPE(__a));
    }

    generate

    template <class ForwardIterator, class Generator>
    void generate ( ForwardIterator first, ForwardIterator last, Generator gen )
    {
        while (first != last) 
        {
            *first = gen();
            ++first;
        }
    }

    generate_n

      返回值是first+n,generate和generate_n中的gen会被调用n(或first+n)次,而非只在循环外调用一次,这一点很重要,因为Generate不一定会在每次调用时候都返回相同的结果,因此generate允许从文件读入,取局部状态的值并更改。

    template <class OutputIterator, class Size, class Generator>
    OutputIterator generate_n ( OutputIterator first, Size n,const Generator gen )
    {
        while (n>0) 
        {
            *first = gen();
            ++first; 
            --n;
        }
    }

    mismatch

      与equal类似,但会返回哪里不同,equal(f1,l1,f2)与misatch(f1,l1,f2)。first==l1等价,如果相等,返回两个序列的last

    //版本一:调用重载operator==比较元素 
    template <class InputIterator1,class InputIterator2>
    pair<InputIterator1,InputIterator2> mismatch(InputIterator1 first1,InputIterator1 last1,InputIterator2 first2)
    {
        while (first1 != last1 && *first1 == *first2) {
            ++first1;
            ++first2;
        }
        return pair<InputIterator1,InputIterator2>(first1, first2);//返回pair类型,first1指向第一个序列不匹配点,first2指向第二个序列不匹配点
    }
    //版本二:调用自己定义的function object来比较 
    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);
    }

    lexicographical_compare

      返回两个序列的字典排序大小,

    1. 如果第一序列元素较小返回true,否则返回false
    2. 到达last1而未到达last2返回true
    3. 到达last2而未到达last1返回false
    4. 同时到达last1和last2(所有元素都匹配)返回false
    //版本一:调用重载operator==比较元素
    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;//第二组还有元素
    }
    
    //版本二:调用自己定义的function object来比较,inputiterator1 value_type可转化为 BinaryPredicate的第一型别等等
    template <class InputIterator1,class InputIterator2,class BinaryPredicate>
    bool lexicographical_compare(InputIterator1 first1,InputIterator1 last1,InputIterator2 first2,InputIterator2,BinaryPredicate binary_pred)
    {
        for ( ; first1 != last1 && first2 != last2; ++first1, ++first2)
        {
            if (comp(*first1, *first2))
                return true;
            if (comp(*first2, *first1))
                return false;
        }
        return first1 == last1 && first2 != last2; 
    }

    copy

    1. 为outputIterator中的元素赋值而不是产生新的元素,所以outputIterator不能是空的
    2. 如要元素安插序列,使用insert成员函数或使用copy搭配insert_iterator适配器
    3. 如果输出区间的起头与输入区间重叠,则不能使用copy,如果输出区间的尾端与输入区间重叠,则可以使用;copy_backward的限制与copy相反

      与strcpy、memmove的情况类似,具体看下图

      在偏特化与全特化中分析过, 最适合的函数会优先调用, 普通函数优先级大于模板函数

    template <class InputIterator, class OutputIterator>
    inline OutputIterator copy(InputIterator first, InputIterator last, OutputIterator result)
    {
      return __copy_dispatch<InputIterator,OutputIterator>()(first, last, result);
    }
    // 重载 在偏特化与全特化中分析过, 最适合的函数会优先调用, 普通函数优于模板函数
    inline char* copy(const char* first, const char* last, char* result) {
        // 直接调用memmove效率最高
      memmove(result, first, last - first);
      return result + (last - first);
    }
    inline wchar_t* copy(const wchar_t* first, const wchar_t* last, wchar_t* result) {
        // 直接调用memmove效率最高
      memmove(result, first, sizeof(wchar_t) * (last - first));
      return result + (last - first);
    }
    
    template <class InputIterator, class OutputIterator>
    struct __copy_dispatch//通过传入参数的迭代器类型再进行优化处理
    {
      OutputIterator operator()(InputIterator first, InputIterator last,
                                OutputIterator result) {
          // iterator_category获取迭代器类型, 不同迭代器选择不同的重载函数
        return __copy(first, last, result, iterator_category(first));
      }
    };
    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());
      }
    };
    
    template <class T>
    struct __copy_dispatch<T*, T*>
    {
      T* operator()(T* first, T* last, T* result) {
        typedef typename __type_traits<T>::has_trivial_assignment_operator t;
        return __copy_t(first, last, result, t());
      }
    };
    
    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>
    //优化处理
    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);
    }
    //优化处理
    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);
    }
    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;
    }

    copy_backward

      从结果集的尾端到头端复制元素,返回result-(last-first)

    template <class BidirectionalIterator1,class BidirectionalIterator2>
    OutputeIterator copy(BidirectionalIterator1 first,BidirectionalIterator1 last,BidirectionalIterator2 result);
  • 相关阅读:
    结构型模式代理&适配器
    创建型模式单例&工厂&建造者&原型
    结构型模式装饰者&桥接&门面
    python中列表(list)的使用
    Win2003 域控制器设置和客户端安装
    Python下冒泡排序的实现
    乔布斯在斯坦福大学毕业典礼上的演讲
    字符串替换
    统计文件中某一字符串出现的次数
    [用户 'sa' 登录失败。原因: 该帐户被禁用]的解决方案
  • 原文地址:https://www.cnblogs.com/tianzeng/p/10403507.html
Copyright © 2011-2022 走看看