STL 源码剖析 算法 stl_algo.h -- rotate

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie


rotate
--------------------------------------------------------------

描述:将[first, middle) 内的元素和[middle, last) 内的元素互换。

/*------------------------------------------------------------
*分派函数(dispatch function)
*/
template <class ForwardIterator>
inline void rotate(ForwardIterator first, ForwardIterator middle, ForwardIterator last){
	if(first == middle || middle == last) return ;
	__rotate(first, middle, last, distance_type(first), iterator_category(first));
}

下面根据不同的迭代器类型完成三个旋转操作

rotate 的 forward iterator 版
思路:
1.以短段为依据,对应元素逐一对调
2.调整,对新的前、后段再作交换
3.当两段都结束时,循环结束

复杂度:O(n)
template<class ForwardIterator, class Distance>
void __rotate(ForwardIterator first, ForwardIterator middle, 
			ForwardIterator last, Distance*, forward_iterator_tag){
	for(ForwardIterator i = middle ; ; ){
		iter_swap(first, i); //前段,后段的元素一一交换
		++first; ++i;  // 双双前进 1
		// 以下判断是前段[first, middle)先结束还是后段 [middle, last) 后结束
		if(first == middle){ //前段结束了
			if(i == last) return; //如果后段同时也结束,整个就结束了
			middle = i;
		}
		else if(i == last){ //后段先结束
			i = middle; // 调整,准备对新的的前、后段再作交换
		}
	}
}

rotate 的 bidirectional iterator 版
思路:
1.对前段逆转
2.对后段逆转
3.对整体逆转
复杂度:O(n)

template<class BidirectionalIterator, class Distance>
void __rotate(BidirectionalIterator first, BidirectionalIterator middle, 
		BidirectionalIterator last, Distance *,
		bidirectional_iterator_tag){
	reverse(first, middle);
	reverse(middle,last);
	reverse(first, last);
}

rotate 的 random access iterator 版 --> ?? 看不太懂。。。
template<class RandomAccessIterator, class Distance>
void __rotate(RandomAccessIterator first, RandomAccessIterator middle,
		RandomAccessIterator last, Distance *,
		random_access_iterator_tag){
	//取全长和前段长度的最大公因子
	Distance n = __gcd(last - first, middle - first);
	while(n--){
		__rotate_cycle(first, last, first + n, middle - first, value_type(first));
	}
}

template <class EuclideanRingElement>
EuclideanRingElement __gcd(EuclideanRingElement m, EuclideanRingElement n)
{
  while (n != 0) {
    EuclideanRingElement t = m % n;
    m = n;
    n = t;
  }
  return m;
}

template <class RandomAccessIterator, class Distance, class T>
void __rotate_cycle(RandomAccessIterator first, RandomAccessIterator last,
                    RandomAccessIterator initial, Distance shift, T*) {
  T value = *initial;
  RandomAccessIterator ptr1 = initial;
  RandomAccessIterator ptr2 = ptr1 + shift;
  while (ptr2 != initial) {
    *ptr1 = *ptr2;
    ptr1 = ptr2;
    if (last - ptr2 > shift)
      ptr2 += shift;
    else
      ptr2 = first + (shift - (last - ptr2));
  }
  *ptr1 = value;
}

示例:
char alpha[] = "abcdefghijklmnopqrstuvwxyz";
rotate(alpha, alpha + 13, alpha + 26);
printf("%s\n", alpha);
// The output is nopqrstuvwxyzabcdefghijklm



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值