题目:一个容器(数组)将[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 <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));
}
//针对ForwardIterator版:
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; // 调整,准备对新的的前、后段再作交换
}
}
}
//针对Bidirectional iterator版
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);
}
//针对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));
}
}
//实例编程:数组
void int_swap(int &lhs,int &rhs)
{
lhs = lhs ^ rhs;
rhs = lhs ^ rhs;
lhs = lhs ^ rhs;
举例:数字序列{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 <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));
}
//针对ForwardIterator版:
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; // 调整,准备对新的的前、后段再作交换
}
}
}
//针对Bidirectional iterator版
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);
}
//针对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));
}
}
//实例编程:数组
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;
}
}