GeekBand C++ STL与泛型编程 第七周笔记

来源:互联网 发布:windows内核安全编程 编辑:程序博客网 时间:2024/05/22 06:04

  进入STL开始,笔记的容易倒是不零散。第七周的笔记主要是变易算法,排序,数值算法和内存分配器。同非变易算法一样,变易算法的函数种类较多,实例代码也较多。下面开始整理。内容来源这次会注释在每一段内容的后边。

  变易算法:STL的变易算法是一组能够修改容器元素数据的模板函数,可进行序列容器的复制、交换、替换、填充、移除、旋转等。这些算法对迭代器有较高的要求,具体的迭代器类型随各个算法而定,或向前迭代器、或双向迭代器、又或者是随机迭代器,以提供算法所需要的迭代器操作。应用变易算法时,先要检查容器的迭代器是否符合要求,防止产生编译错误。

  C++STL提供一个用于容器间元素拷贝的copy算法,将迭代区间[first,last)的元素复制到由复制目标迭代器result给定的区间[result,result+(last-first))中,原型如下:

template <class InputIterator, class OutputIterator>  OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result);

  与copy算法相似,copy_backward算法也是将一个迭代器区间元素复制到另一迭代器区间上,只是复制的过程是从最后的元素开始复制,直到首元素复制出来。 
它使用的原型如下,将迭代器区间[first,last)的元素,复制到以result为结束位置的区间[result-(last-first))中,顺序为*(last-1)复制到*(result-1)、*(last-2)复制到*(result-2)、*(last-3)复制到*(result-3)、……

template<class BidirectionalIterator1, class BidirectionalIterator2>  BidirectionalIterator2 copy_backward ( BidirectionalIterator1 first,                                         BidirectionalIterator1 last,                                         BidirectionalIterator2 result ){  while (last!=first) *(--result) = *(--last);  return result;}

  虽然大多数容器的内部提供了swap函数,但c++STL还是以更一般的迭代器形式,提供更一般的swap算法来实现两个元素的交换。

template <class T> void swap ( T& a, T& b ){  T c(a); a=b; b=c;}
    iter_swap算法是swap算法的迭代器形式,使交换算法更易用于一般的容器。

template <class ForwardIterator1, class ForwardIterator2>  void iter_swap (ForwardIterator1 a, ForwardIterator2 b){  swap (*a, *b);}

  swap_ranges算法用于进行两个迭代器区间元素的交换。它的使用原型如下,将[first1,last1)迭代器区间的元素,与[first2,first2+(last1-first1))迭代器区间元素交换,其中*first1和*first2交换,*(first1+1)和*(first2+1)交换、……、*(last1-1)和*(first2+(last1-first1)-1)交换。  

template<class ForwardIterator1, class ForwardIterator2>  ForwardIterator2 swap_ranges (ForwardIterator1 first1, ForwardIterator1 last1,                                ForwardIterator2 first2){  while (first1!=last1) {    swap (*first1, *first2);    ++first1; ++first2;  }  return first2;}
  transform算法用于实行容器元素的变换操作。如下两个使用原型,一个将迭代器区间[first,last)中元素,执行一元函数对象op操作,变换后的结果存放在[result,result+(last-first))区间中。另一个将迭代器区间[first1,last1)的元素*i,依次与[first2,first2+(last-first))的元素*j,执行二元函数操作binary_op(*i,*j),变换结果放在[result,result+(last1-first1))区间。

template <class InputIterator, class OutputIterator, class UnaryOperation>  OutputIterator transform (InputIterator first1, InputIterator last1,                            OutputIterator result, UnaryOperation op);template <class InputIterator1, class InputIterator2,          class OutputIterator, class BinaryOperation>  OutputIterator transform (InputIterator1 first1, InputIterator1 last1,                            InputIterator2 first2, OutputIterator result,                            BinaryOperation binary_op);//transform算法函数的代码template <class InputIterator, class OutputIterator, class UnaryOperator>  OutputIterator transform (InputIterator first1, InputIterator last1,                            OutputIterator result, UnaryOperator op){  while (first1 != last1) {    *result = op(*first1);  // or: *result=binary_op(*first1,*first2++);    ++result; ++first1;  }  return result;}
    replace算法将指定元素值替换为新值,使用原型如下,将迭代器区间[first,last)中值为old_value的元素全部替换为new_value值。

template <class ForwardIterator, class T>  void replace (ForwardIterator first, ForwardIterator last,                const T& old_value, const T& new_value){  while (first!=last) {    if (*first == old_value) *first=new_value;    ++first;  }}
    replace_if算法是replace算法的一个带谓词判断的版本,使用原型如下,将迭代器区间[first,last)中满足一元谓词判断条件的元素全部替换为new_value。

template < class ForwardIterator, class UnaryPredicate, class T >  void replace_if (ForwardIterator first, ForwardIterator last,                   UnaryPredicate pred, const T& new_value){  while (first!=last) {    if (pred(*first)) *first=new_value;    ++first;  }}
  replace_copy算法先进行元素替换,再将元素复制到新容器。它的使用原型如下,将迭代器区间[first,last)中元素值为old_value的元素替换为new_value,并全部拷贝到[result,result+(last-first))中(包括不替换的元素),迭代器[first,last)区间上的元素仍保持不变。
emplate <class InputIterator, class OutputIterator, class T>  OutputIterator replace_copy (InputIterator first, InputIterator last,                               OutputIterator result, const T& old_value, const T& new_value){  while (first!=last) {    *result = (*first==old_value)? new_value: *first;    ++first; ++result;  }  return result;}
  replace_copy_if算法是replace_copy算法的一个带谓词判断的版本,使用原型如下,将迭代器区间[first,last)中满足一元谓词判断pred的元素替换为new_value,然后全部拷贝到[result,result+(last-first))中(包括不替换的元素),迭代器[first,last)区间的元素仍保持不变。
template<class InputIter, class OutputIter, class Predicate, class T>OutputIter replace_copy_if(InputIter first, InputIter last,                          OutputIter result,                          Predicate pred, const T& new_value){    for( ; first!=last; ++first, ++result)     *result=pred(*first)? new_value : *first;    return result;}
  fill算法将同一个值填充到容器的一个或多个元素处,使用原型如下,将元素区间[first,last)上的元素全部填充为value值。
template <class ForwardIterator, class T>  void fill (ForwardIterator first, ForwardIterator last, const T& val){  while (first != last) {    *first = val;    ++first;  }}
  类似于fill算法,fill_n算法可指定填充的元素个数。它的使用原型如下,将迭代器区间[first,first+n)个元素的值填充为value新值。

template <class OutputIterator, class Size, class T>  OutputIterator fill_n (OutputIterator first, Size n, const T& val){  while (n>0) {    *first = val;    ++first; --n;  }  return first;     // since C++11}
  generate算法为容器生成新元素,使用原型如下,将gen发生器生成的一系列元素存入迭代器区间[first,last)的元素区域处。

template <class ForwardIterator, class Generator>  void generate ( ForwardIterator first, ForwardIterator last, Generator gen ){  while (first != last) {    *first = gen();    ++first;  }}
  与generate算法类似,但generate_n算法限定了可填入容器的数值个数。它的使用原型如下,将迭代器区间[first,first+n)位置处的n个元素,填入由发生器gen生成的数值。

template <class OutputIterator, class Size, class Generator>  void generate_n ( OutputIterator first, Size n, Generator gen ){  while (n>0) {    *first = gen();    ++first; --n;  }}
  remove_copy算法实质上是一个条件复制,将容器中不等于某个给定值的元素复制到新容器。使用原型如下,将迭代器区间[first,last)上不取value的所有元素复制到迭代器区间[result,result+n),n为实际复制的元素个数。
template <class InputIterator, class OutputIterator, class T>  OutputIterator remove_copy (InputIterator first, InputIterator last,                              OutputIterator result, const T& val){  while (first!=last) {    if (!(*first == val)) {      *result = *first;      ++result;    }    ++first;  }  return result;}
  remove_copy_if实际上是remove_copy函数的一个带谓词判断的版本,使用原型如下,将迭代器区间[first,last)上不满足谓词判断条件pred的元素,拷贝到有迭代器result为起始位置的迭代器区间中。

template <class InputIterator, class OutputIterator, class UnaryPredicate>  OutputIterator remove_copy_if (InputIterator first, InputIterator last,                                 OutputIterator result, UnaryPredicate pred){  while (first!=last) {    if (!pred(*first)) {      *result = *first;      ++result;    }    ++first;  }  return result;}

  remove算法是将容器中等于某个给定值的元素全部除去。使用原型如下,将迭代器区间将迭代器区间[first,last)上不等于value的元素,复制回迭代器区间[first,result),其中result是算法函数返回的迭代器。迭代器区间[result,last)的元素仍然保持不变。

template <class ForwardIterator, class T>  ForwardIterator remove (ForwardIterator first, ForwardIterator last, const T& val){  ForwardIterator result = first;  while (first!=last) {    if (!(*first == val)) {      *result = *first;      ++result;    }    ++first;  }  return result;}
    remove_if是remove函数的一个带谓词判断的版本,使用原型如下,将迭代器区间[first,last)上不满足谓词判断条件pred的元素,复制回迭代器区间[first,result),result是算法返回值。[result,last)上元素保持不变。  
template <class ForwardIterator, class UnaryPredicate>  ForwardIterator remove_if (ForwardIterator first, ForwardIterator last,                             UnaryPredicate pred){  ForwardIterator result = first;  while (first!=last) {    if (!pred(*first)) {      *result = *first;      ++result;    }    ++first;  }  return result;}
  unique_copy用于复制不连续的重复元素。它有如下两个使用原型,将迭代器区间[first,last)中邻近相异的元素,复制到以result为起点的迭代器区间。
template <class InputIterator, class OutputIterator>  OutputIterator unique_copy (InputIterator first, InputIterator last,                              OutputIterator result);template <class InputIterator, class OutputIterator, class BinaryPredicate>  OutputIterator unique_copy (InputIterator first, InputIterator last,                              OutputIterator result, BinaryPredicate pred);template <class InputIterator, class OutputIterator>  OutputIterator unique_copy (InputIterator first, InputIterator last,                              OutputIterator result){  if (first==last) return result;  *result = *first;  while (++first != last) {    typename iterator_traits<InputIterator>::value_type val = *first;    if (!(*result == val))   // or: if (!pred(*result,val)) for version (2)      *(++result)=val;  }  return ++result;}
  unique算法用于剔除容器中连续重复元素,使用原型如下,将迭代器区间[first,last)中不连续重复的元素或不满足谓词判断条件的元素,复制回迭代区间[first,result),result为算法返回值。[result,last)区间的元素,依然维持不变。

template <class ForwardIterator>  ForwardIterator unique (ForwardIterator first, ForwardIterator last);template <class ForwardIterator, class BinaryPredicate>  ForwardIterator unique (ForwardIterator first, ForwardIterator last,                          BinaryPredicate pred);template <class ForwardIterator>  ForwardIterator unique (ForwardIterator first, ForwardIterator last){  if (first==last) return last;  ForwardIterator result = first;  while (++first != last)  {    if (!(*result == *first))  // or: if (!pred(*result,*first)) for version (2)      *(++result)=*first;  }  return ++result;}
   reverse算法用于容器元素的反向排列,使用原型如下,将迭代区间[first,last)的元素反向排列。
template <class BidirectionalIterator>  void reverse (BidirectionalIterator first, BidirectionalIterator last){  while ((first!=last)&&(first!=--last)) {    std::iter_swap (first,last);    ++first;  }}
  reverse_copy算法用于反向复制容器元素,使用原型如下,将迭代器区间[first,last)中的元素,以反向顺序复制到迭代器区间[result,result+(last-first))。

template <class BidirectionalIterator, class OutputIterator>  OutputIterator reverse_copy (BidirectionalIterator first,                               BidirectionalIterator last, OutputIterator result){  while (first!=last) {    --last;    *result = *last;    ++result;  }  return result;}
  rotate算法用于旋转某个迭代器区间的元素。使用原型如下,将迭代器区间[first,last)中元素以middle为支点,左旋转[first,middle)元素到[middle,last)的一侧。

template <class ForwardIterator>  void rotate (ForwardIterator first, ForwardIterator middle,               ForwardIterator last){  ForwardIterator next = middle;  while (first!=next)  {    swap (*first++,*next++);    if (next==last) next=middle;    else if (first==middle) middle=next;  }}

  (变易算法内容来自程序园http://www.voidcn.com/blog/lsh_2013/article/p-2789196.html)


  排序:STL支持几种泛型排序,像sort,stable_sort,partial_sort,list::sort,但都有一些限制。

  sort和partial_sort只支持支持随机访问迭代器RandomAccessIterator的序列,像vector,但不支持list;list::sort只支持list排序;stable_sort支持支持双向迭代器BidirectionalIterator的序列,如vector和list等,但不能支持数组(包括指针寻址的)序列。

  数值算法:是一组对容器元素进行数值计算的模板函数,包括容器元素求和 accumulate 、两序列元素的内积 inner_product 、容器元素的一系列部分元素和 partial_sum 、容器每对相邻元素的差。数值计算的方法虽然不多,但是需要很高的灵活性。比如,  容器元素求和的 accumulate 算法,可设置运算为乘法操作,就可变成对容器元素的阶乘计算;两序列容器的元素内积 inner_product 算法,可推广到对应元素两两执行一种运算后,再将结果执行另一种另一种运算;容器元素的部分元素和 parital_sum 算法,可设置相应的操作运算,变成一系列部分元素的阶乘计算;相邻元素差 adjacent_difference 算法,可转换为计算相邻元素的和或者乘积 等等。(来源博客园博主,小乌龟的笔记基本)

  分配器:在C++编程中,分配器(英语:allocator)是C++标准库的重要组成部分。C++的库中定义了多种被统称为“容器”的数据结构(如链表、集合等),这些容器的共同特征之一,就是其大小可以在程序的运行时改变;为了实现这一点,进行动态内存分配就显得尤为必要,在此分配器就用于处理容器对内存的分配与释放请求。换句话说,分配器用于封装STL容器在内存管理上的低层细节。

  分配器最早由亚历山大·斯特潘诺夫作为C++标准模板库(Standard Template Library,简称STL)的一部分发明,其初衷是创造一种能“使库更加灵活,并能独立于底层数据模型的方法”,并允许程序员在库中利用自定义的指针和引用类型;但在将标准模板库纳入C++标准时,C++标准委员会意识到对数据模型的完全抽象化处理会带来不可接受的性能损耗,为作折中,标准中对分配器的限制变得更加严格,而有鉴于此,与斯特潘诺夫原先的设想相比,现有标准所描述的分配器可定制程度已大大受限。

 虽然分配器的定制有所限制,但在许多情况下,仍需要用到自定义的分配器,而这一般是为封装对不同类型内存空间(如共享内存与已回收内存)的访问方式,或在使用内存池进行内存分配时提高性能而为。(维基百科)

  

0 0
原创粉丝点击