zoukankan      html  css  js  c++  java
  • 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
    ", alpha);
    // The output is nopqrstuvwxyzabcdefghijklm
    



  • 相关阅读:
    设置div内的内容不能被选中
    js中!和!!的区别及用法
    echars自定义提示框位置
    数组排序
    查询一个表的不同数据,显示到一个表
    document.body
    设置fixed,横向滚动条失效
    scrollTop
    JS 数组
    JS 数学函数
  • 原文地址:https://www.cnblogs.com/wzjhoutai/p/6764374.html
Copyright © 2011-2022 走看看