STL之基础算法(二)

/ generate and generate_n
//将仿函数gen的处理结果填充在[first, last)区间内所有元素上,所谓填写
//就是用迭代器所指元素的assignment操作
//注意:对于用户自定义类型要提供operator =() 

template <class _ForwardIter, class _Generator>
void generate(_ForwardIter __first, _ForwardIter __last, _Generator __gen) {
  __STL_REQUIRES(_ForwardIter, _ForwardIterator);
  __STL_GENERATOR_CHECK(_Generator, 
          typename iterator_traits<_ForwardIter>::value_type);
  for ( ; __first != __last; ++__first)//遍历整个序列
    *__first = __gen();
}
//将仿函数gen的处理结果填充在first开始的n个元素上,所谓填写
//就是用迭代器所指元素的assignment操作
template <class _OutputIter, class _Size, class _Generator>
_OutputIter generate_n(_OutputIter __first, _Size __n, _Generator __gen) {
  __STL_REQUIRES(_OutputIter, _OutputIterator);
  for ( ; __n > 0; --__n, ++__first)//只限于n个元素
    *__first = __gen();
  return __first;
}
/*
下面是计算set集合的相关算法,分别是并集set_union,差集set_difference,交集set_intersection
和对称差集set_symmetric_difference,这是个函数都提供了两个版本的函数原型
第一个版本是采用默认的排序比较方式 operator<
第二个版本是用户通过comp自行指定排序方式
注意:这四个算法接受的输入区间都是有序的,输出也是有序的
*/

// Set algorithms: includes, set_union, set_intersection, set_difference,
// set_symmetric_difference.  All of these algorithms have the precondition
// that their input ranges are sorted and the postcondition that their output
// ranges are sorted.

// 判断[first1, last1)是否包含[first2, last2),  
// 注意: 两个区间要保证有序,默认排序方式是operator<,若要自行定义排序方式,则调用第二版本;
template <class _InputIter1, class _InputIter2>
bool includes(_InputIter1 __first1, _InputIter1 __last1,
              _InputIter2 __first2, _InputIter2 __last2) {
  __STL_REQUIRES(_InputIter1, _InputIterator);
  __STL_REQUIRES(_InputIter2, _InputIterator);
  __STL_REQUIRES_SAME_TYPE(
       typename iterator_traits<_InputIter1>::value_type,
       typename iterator_traits<_InputIter2>::value_type);
  __STL_REQUIRES(typename iterator_traits<_InputIter1>::value_type,
                 _LessThanComparable);
  while (__first1 != __last1 && __first2 != __last2)//遍历两个区间
    if (*__first2 < *__first1)//first2小于first1表示不包含
      return false;//返回FALSE
    else if(*__first1 < *__first2)//若first1小于first2 
      ++__first1;//寻找第一个区间下一个位置
    else
      ++__first1, ++__first2;//若first2等于first1,遍历两区间的下一位置

  return __first2 == __last2;//若第二个区间先到达尾端,则返回TRUE
}

//版本二:用户通过comp自行指定排序方式
template <class _InputIter1, class _InputIter2, class _Compare>
bool includes(_InputIter1 __first1, _InputIter1 __last1,
              _InputIter2 __first2, _InputIter2 __last2, _Compare __comp) {
  __STL_REQUIRES(_InputIter1, _InputIterator);
  __STL_REQUIRES(_InputIter2, _InputIterator);
  __STL_REQUIRES_SAME_TYPE(
       typename iterator_traits<_InputIter1>::value_type,
       typename iterator_traits<_InputIter2>::value_type);
  __STL_BINARY_FUNCTION_CHECK(_Compare, bool,
       typename iterator_traits<_InputIter1>::value_type,
       typename iterator_traits<_InputIter2>::value_type);
  while (__first1 != __last1 && __first2 != __last2)
    if (__comp(*__first2, *__first1))
      return false;
    else if(__comp(*__first1, *__first2)) 
      ++__first1;
    else
      ++__first1, ++__first2;

  return __first2 == __last2;
}
// partition, stable_partition, and their auxiliary functions
//若迭代器的类型为forward_iterator_tag,则调用此函数
template <class _ForwardIter, class _Predicate>
_ForwardIter __partition(_ForwardIter __first,
		         _ForwardIter __last,
			 _Predicate   __pred,
			 forward_iterator_tag) {
  if (__first == __last) return __first;//若为空,直接退出

  while (__pred(*__first))//若pred出first的值为true
    if (++__first == __last) return __first;//先移动迭代器first,在判断是否到达尾端last

  _ForwardIter __next = __first;//继续判断

  while (++__next != __last)//若下一个位置依然不是尾端
    if (__pred(*__next)) {//继续pred出next的值,若为true
      swap(*__first, *__next);//交换值
      ++__first;//继续下一位置
    }

  return __first;
}
//若迭代器的类型为bidirectional_iterator_tag,则调用此函数
template <class _BidirectionalIter, class _Predicate>
_BidirectionalIter __partition(_BidirectionalIter __first,
                               _BidirectionalIter __last,
			       _Predicate __pred,
			       bidirectional_iterator_tag) {
  while (true) {
    while (true)
      if (__first == __last)//若为空
        return __first;//直接退出
      else if (__pred(*__first))//first的值符合不移动条件,则不移动该值
        ++__first;//只移动迭代器
      else//若头指针符合移动
        break;//跳出循环
    --__last;//尾指针回溯
    while (true)
      if (__first == __last)//头指针等于尾指针
        return __first;//操作结束
      else if (!__pred(*__last))//尾指针的元素符合不移动操作
        --__last;//至移动迭代器,并不移动具体元素
      else//尾指针的元素符合移动操作
        break;//跳出循环
    iter_swap(__first, __last);//头尾指针交换元素
    ++__first;//准备下一次循环
  }
}
//将区间[first,last)的元素进行排序,被pred判断为true的放在区间的前段,判定为false的放在区间后段
//该算算可能会使元素的元素位置放生改变.
/*
算法功能:Rearranges the elements from the range [first,last), in such a way that all the elements
for which pred returns true precede all those for which it returns false. 
The iterator returned points to the first element of the second group.

算法原型:
	template <class BidirectionalIterator, class UnaryPredicate>
	BidirectionalIterator partition (BidirectionalIterator first,
                                   BidirectionalIterator last, UnaryPredicate pred);
*/
template <class _ForwardIter, class _Predicate>
inline _ForwardIter partition(_ForwardIter __first,
   			      _ForwardIter __last,
			      _Predicate   __pred) {
  __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator);
  __STL_UNARY_FUNCTION_CHECK(_Predicate, bool, 
        typename iterator_traits<_ForwardIter>::value_type);
  //首先萃取出迭代器first的类型,根据迭代器的类型调用不同的函数
  return __partition(__first, __last, __pred, __ITERATOR_CATEGORY(__first));
}



猜你喜欢

转载自blog.csdn.net/dongyu_1989/article/details/80075831
今日推荐