在书上提到了两种解法,分别如下,习题中有这么一个问题:i和n的最大公约数如何才能被程序用到?一时间没有思路,看看STL是怎么实现的,果然用到了最大公约数。最后就介绍STL中的rotate算法。
法一:从a[0]开始,每隔i位,将后面的元素移到前面去,将a[i]移到a[0],a[2*i]移到a[i]上,若k*i大于n了,则取模。直到再次遇到a[0]时停止。这时如果还没将所有元素都移动过一遍,则从a[1]开始再次移动。
vector<int >
a;
void rotate(vector <int > a , int i )
{
int totalmove
= 0; //计算移动的总步数
for( int j
= 0; j < i; j++) {
int p
= j; //保存将要被覆盖的点
int cur
= (p + i) % a.size(); //这一次要移动的点
int tmp
= a[j]; //保存第一个元素
while (cur
!= j) {
a[p]
= a[cur];
p = cur;
cur = (p + i)
% a.size();
totalmove++;
}
a[p]
= tmp; //将第一个元素放到位置
if(totalmove
== a.size() - 1) { //因为少一个第一个元素的移动,所以步数减一
break; //全部移动过了,停止
}
}
ostream_iterator<int >
oit(cout, " ");
copy( a.begin(), a.end(),
oit);
cout<<endl;
}
法二:将数组分成两个部分,mn,我们想要达到的目的是nm,则nm = (n^rm^r)^r。
void reverse(int m , int n )
{
while ( m < n)
{
int tmp
= a[ m];
a[ m]
= a[ n];
a[ n]
= tmp;
m++, n--;
}
}
void rotate2(vector <int > a , int i )
{
int r
= i % a.size();
reverse(0, i -
1); //reverse函数的作用是倒转指定区域的元素
reverse( i, a.size()
- 1);
reverse(0, a.size()
- 1);
}