STL复习之算法三

1、rotate(s,m,l),将区间[m,l)序列的元素整体移动到区间[s,m)前面。返回为void。

函数原型:

template<class ForwardIterator,class Distance>
void __rotate(ForwardIterator first,ForwardIterator middle,
ForwardIterator last,Distance*,forward_iterator_tag)
{

    for(ForwardIterator i=middle;;){
      iterator_swap(first,i);
      ++first;
      ++i;
      
      if(first==middle) //前半段走完了
      { 
         if(i==last)    //后半段也走完了,正好结束算法
            return;
         middle=i;      //否则,前半段元素少于后半段元素,重新确定中点,对新的前后半段进行交换
      }
      else if(i==last)  //后半段先走完了,调整,对新的前后半段进行调整
         i=middle;
    }
}

测试代码:

void traverseEle(const std::vector<int> array)
{
    int index=1;
    for(auto it=array.begin();it!=array.end();++it)
        std::cout<</*index++<<"\t"<<*/*it<<"\t";

    std::cout<<std::endl;
}
//测试函数
int main()
{
    std::vector<int> intArray={1,2,3,4,5,6,7,8};
    std::cout<<"before rotate:\n";
    traverseEle(intArray);

    std::rotate(intArray.begin(),
                std::find(intArray.begin(),intArray.end(),7),
                intArray.end());
    std::cout<<"after rotate:\n";
    traverseEle(intArray);

    std::cout<<std::endl;
    return 0;
}

执行结果:

2、search_n(s,e,count,value)。在给定的区间[s,e)内寻找连续个count值为value的序列的起点,若找不到,返回被找区间的终点,即e。

函数原型:

  template<typename _RandomAccessIter, typename _Integer,
	   typename _UnaryPredicate>
    _RandomAccessIter
    __search_n_aux(_RandomAccessIter __first, _RandomAccessIter __last,
		   _Integer __count, _UnaryPredicate __unary_pred,
		   std::random_access_iterator_tag)

算法实现:

  template<typename _RandomAccessIter, typename _Integer,
	   typename _UnaryPredicate>
    _RandomAccessIter
    __search_n_aux(_RandomAccessIter __first, _RandomAccessIter __last,
		   _Integer __count, _UnaryPredicate __unary_pred,
		   std::random_access_iterator_tag)
    {
      typedef typename std::iterator_traits<_RandomAccessIter>::difference_type
	_DistanceType;

      _DistanceType __tailSize = __last - __first;
      _DistanceType __remainder = __count;

     //被找的区间>=要找的区间的尺寸
      while (__remainder <= __tailSize) // the main loop...
	{
	  __first += __remainder;   //指向往回找的起点的下一个元素
	  __tailSize -= __remainder;//缩小被找的区间
	  // __first here is always pointing to one past the last element of
	  // next possible match.
	  _RandomAccessIter __backTrack = __first; 
	  while (__unary_pred(--__backTrack))
	    {
          //当前迭代器所指之元素满足条件且已经找完了
	      if (--__remainder == 0)
	        return (__first - __count); //返回找到这段区间的起点
          //未找完,则继续往回找
	    }
	  __remainder = __count + 1 - (__first - __backTrack);
	}
      return __last; // Failure
    }

上面的代码不是很好理解,还是参考《STL源码剖析》的第367页理解较为简单。

测试函数:

//测试函数
int main()
{
    std::vector<int> intArray={1,2,3,4,5,6,6,7,8};

    auto it=std::search_n(intArray.begin(),intArray.end(),2,6);

    if(it!=intArray.end())
        std::cout<<"find success!\n";
    else
    {
        std::cout<<"find failed!\n";
    }

    return 0;
}

运行截图:

猜你喜欢

转载自blog.csdn.net/weixin_40825228/article/details/81075665