利用STL算法高效实现容器的循环移位

题目:一个容器(数组)将[first,middle]内的元素和[middle,last]内的元素互换。

举例:数字序列{1,2,3,4,5,6,7},对元素3做上述操作后,数字序列{3,4,5,6,7,1,2}。

一、STL基本算法rotate对该问题进行高效解决:
1.基础知识分析:
  1)迭代器分类:Input Iterator:该迭代器所指的对象不允许外界改变,只读,举例const_iterator、istream_iterator;Output Iterator:唯写,举例ostream_iterator;Forward 
Iterator:允许“写入型”算法,可以在区间内进行读写操作;Bidirectional Iterator:可以双向移动。Random Access Iterator:前四种迭代器都只供应一部分指针算数能力(前三种只支持operator++,第四种再加上operator--),第五种涵盖所有的指针算数能力。
  2)gcd,求解最大公因子,利用辗转相除法:设两数为a、b(a>b),求a和b最大公约数(a,b)的步骤如下:用a除以b,得a÷b=q......r1(0≤r1)。若r1=0,则(a,b)=b;若r1≠0,则再用b除以r1,得b÷r1=q......r2 (0≤r2).若r2=0,则(a,b)=r1,若r2≠0,则继续用r1除以r2,……如此下去,直到能整除为止。其最后一个非零除数即为(a,b)的最大公约数。
  3)iter_swap(iterator1,iterator2),两个迭代器内容交换。
  4)reverse(iterator1,iterator2)将序列[iterator1,iterator2)的元素在原容器中颠倒重排。例如序列{0,1,1,3,5}颠倒重排后为{5,3,1,1,0}
  5)distance()函数,用于计算两个迭代器之间的距离。针对不同的迭代器类型,它可以有不同的计算方式,带来不同的效率。

//分派函数:
  template  
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));  
}  

//针对ForwardIterator版:
template  
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; // 调整,准备对新的的前、后段再作交换  
        }  
    }  
}  

//针对Bidirectional iterator版
template  
void __rotate(BidirectionalIterator first, BidirectionalIterator middle,   
        BidirectionalIterator last, Distance *,  
        bidirectional_iterator_tag){  
    reverse(first, middle);  
    reverse(middle,last);  
    reverse(first, last);  
}  

//针对random access iterator版
template  
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));  
    }  
}

//实例编程:数组
void int_swap(int &lhs,int &rhs)
{
    lhs = lhs ^ rhs;
    rhs = lhs ^ rhs;
    lhs = lhs ^ rhs;

}

void RotateForward(int arrayTemp[],int first,int middle,int last)
{
    if(first == middle)||middle== last)return;
    int i = 0;
    for(i = middle;;)
    {
        int_swap(arrayTemp[first],arrayTemp[last]);//交换
        first++;
        i++;
        if(first == middle)
        {
            if(i == last)return;
            middle = i;
        }
        else if(middle == last) i = middle;
    }
}



你可能感兴趣的:(C++)