一、概述
1008很经典的循环右移问题,主要是oj上有几个坑可以记录下来看看。
循环右移一般就是倒过来,倒过来再倒过来,很简单,但是会有一些小地方让你没法子达到满分,这就很蛋疼。
二、分析
如果仅仅只是反转三次,五个样例只能对两个。还有三个是错的。
1、右移为0。
直接通过判断进行输出。
if (m == 0)
{
i = 0;
while (i + 1 != n)
{
printf("%d ", a[i]);
i++;
}
printf("%d", a[i]);
}
2、右移大于数组元素总数,即需要循环右移。
通过取模来模拟循环。
Reserve(a, 0, n - m % n - 1);
Reserve(a, n - m % n, n - 1);
Reserve(a, 0, n - 1);
3、只有一个元素。
通过判断调用参数的正负来分别处理。
if (head < 0 || end < 0 || (end - head) < 0)
return;
都是很简单的问题,只是不容易把所有情况都想到。我是一步一步把这三个问题试出来的。应该还有更好的代码。
三、总结
对于输入元素个数为0,为1,大于总个数等情况要注意,一般在原有基础上打个补丁就好了,但是会导致代码很臃肿,显得智商不是那么高。还可以选择不改变原来的数组,而是改变输出的顺序,这也是可以的。
PS:代码如下:
#include<stdio.h>
void Reserve(int *a, int head, int end)
{
if (head < 0 || end < 0 || (end - head) < 0)
return;
int ex;
int i;
for (i = 0; i <= (end - head) / 2; i++)
{
ex = a[head+i];
a[head + i] = a[end - i];
a[end - i] = ex;
}
}
int main()
{
int n, m;
scanf("%d%d", &n, &m);
int a[100];
int i = 0;
while (i != n)
{
scanf("%d", &a[i]);
i++;
}
if (m == 0)
{
i = 0;
while (i + 1 != n)
{
printf("%d ", a[i]);
i++;
}
printf("%d", a[i]);
}
else
{
Reserve(a, 0, n - m % n - 1);
Reserve(a, n - m % n, n - 1);
Reserve(a, 0, n - 1);
i = 0;
while (i + 1 != n)
{
printf("%d ", a[i]);
i++;
}
printf("%d", a[i]);
}
}