题目要求:在不开辟新的数组前提下,实现数组循环右移;
自己认为如果数学不好的话(就是我),很难想到下面方法:
解释 / 方法
n个字符串循环右移m个位置
首先,m = m%n;
然后执行三次颠倒:
1.前n-m个字符串颠倒
2.后m个字符串颠倒
3.整个字符串颠倒
举例
5个字符串(abcde)循环右移7个位置
首先,m = 7%5,最终m=2;
然后执行三次颠倒:
1.前n-m=3个字符串颠倒结果为:cba|de;
2.后m=2个字符串颠倒结果为: cba|ed;
3.整个字符串颠倒结果为: deabc;
最开始颠倒函数是自己写的,要对下标计算,真的脑壳痛,后来发现algorithm.h 下有这个功能的函数reverse();详细参数请百度;
代码如下,提交请选择g++
#include<bits/stdc++.h>
using namespace std;
void reverse(int num[], int s, int e)
//自写reverse函数,s为颠倒开始下标,e为颠倒结束下标
{
int len=e-s, tmp;
for(int i=0; i<=len/2; i++)
{
tmp = num[s+i];
num[s+i] = num[e-i];
num[e-i] = tmp;
}
}
int main()
{
int n, m, a[100];
scanf("%d %d", &n, &m);
for(int i=0; i<n; i++)
scanf("%d", &a[i]);
int yi = m%n;
if(yi!=0) //一定注意yi不为0才移动,如果等于0,那还是原样
{
reverse(a, 0, n-yi-1);
// for(int i=0; i<n; i++)
// printf("%d ", a[i]);
// printf("\n");
reverse(a, n-yi, n-1);
// for(int i=0; i<n; i++)
// printf("%d ", a[i]);
// printf("\n");
reverse(a, 0, n-1);
/*使用algorithm库代码如下:*/
/*
reverse(a, a+(n-yi));
reverse(a+(n-yi+1), a+n);
reverse(a, a+n);
*/
}
for(int i=0; i<n; i++)
{
if(i==0)
printf("%d", a[i]);
else
printf(" %d", a[i]);
}
printf("\n");
}
最后
特别注意只有m%n!=0,才执行reverse() 函数; 另外,algorithm库中包含了reverse()函数,无需自己写,但是传入的是指针,如果自己写的,则注意传入指针和传入下标的区别;