基本算法(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);

 

posted on 2019-02-19 21:34  tianzeng  阅读(162)  评论(0编辑  收藏  举报

导航