前情提要:n为数组长度,m数组元素向右移动位数,num[n]为待移动数组。
1.适用于特殊情况的开挂方法
可用于数组的数据需要实时输入,不是在代码中写好的情况
/该方法实质上不是移动数组中的元素,而是在输入元素时进行了错位输入,
使其在输入时就已经按需要的顺序排好了,但实际上应该通过将已知数组的
元素进行移动来实现(每个数组元素移动0次)/
#include<iostream>
using namespace std;
int main(){
int n,m;
cin>>n>>m;
m=m%n;
int num[n]={0};
for(int i=m;i<n;i++){
cin>>num[i];
}
for(int i=0;i<m;i++){
cin>>num[i];
}
for(int i=0;i<n;i++){
cout<<num[i];
if(i!=n-1)
cout<<' ';
}
}
2.适用于任何情况的三种方法
2.1 方法一(每个数据移动m次)
方法一:一次右移一位,一共m次循环,移动m位
void move_1(int n,int m,int num[]){
for(int i=0;i<m;i++){
int temp=num[n-1];
for(int j=0;j<n-1;j++){
num[n-1-j]=num[n-1-j-1];
}
num[0]=temp;
}
}
2.2 方法二(每个数据约移动2次)
方法二:前面n-m位翻转,后m位翻转,最后整体翻转
void reversal(int start,int end,int num[]){
int time=(end-start+1)/2;
for(int i=0;i<time;i++){
int temp=num[start+i];
num[start+i]=num[end-i];
num[end-i]=temp;
}
}
void move_2(int n,int m,int num[]){
reversal(0,n-m-1,num);
reversal(n-m,n-1,num);
reversal(0,n-1,num);
}
2.3 方法三(每个数据移动1次)
方法三:先根据“m、n的奇偶”和“m与n/2的关系“进行分类,
(1)n是奇数,m是奇数,m>n/2
(2)n是奇数,m是奇数,m<n/2
(3)n是奇数,m是偶数,m>n/2
(4)n是奇数,m是偶数,m<n/2
(5)n是偶数,m是奇数,m>n/2
(6)n是偶数,m是奇数,m<n/2
(7)n是偶数,m是奇数,m=n/2
(8)n是偶数,m是偶数,m>n/2
(9)n是偶数,m是偶数,m<n/2
(10)n是偶数,m是偶数,m=n/2
各代入一个实例后,总结出可以分为三类
(1)123456为一类,需要一次循环
(把该数组看成一个首位相连的循环队列,先取出数组最后一位即下标为n-1,
在依次把前面的第n-1-m位放到取出的空位置上,
再依次去取前面对应的那位放到已经空出的位置上,直到再次遇到下标n-1则停
止,完成一次循环即可)
(2)8和9为一类,需要2次循环(偶数位上的数和奇数位上的数各进行上面这
类的循环一次)
(3)7和10为一类,需要m次循环(前面m个元素和后面m个元素进行对应的交换)
void move_3(int n,int m,int num[]){
//n%2==0&&n/2==m,循环m次
if(n%2==0&&n/2==m){
//cout<<1<<endl;
for(int i=1;i<=m;i++){
int temp=num[n-i]; //先取出最后一位数
num[n-i]=num[n-i-m];
num[n-i-m]=temp;
}
}
//n%2==0&&m%2==0&&m!=n/2,循环2次
else if(n%2==0&&m%2==0&&m!=n/2){
//cout<<2<<endl;
for(int i=0;i<2;i++){
int temp=num[n-1-i]; //先取出最后一位数
int flag=n-1-i;
if(flag-m<0)
flag=flag+n-m;
else
flag=flag-m;
while(flag!=(n-1-i)){
if(flag+m>n-1-i)
num[flag+m-n]=num[flag];
else
num[flag+m]=num[flag];
if(flag-m<0)
flag=flag+n-m;
else
flag=flag-m;
}
if(flag+m>n-1-i)
num[flag+m-n]=temp;
else
num[flag+m]=temp;
}
}
//循环1次
else{
//cout<<3<<endl;
int temp=num[n-1]; //先取出最后一位数
int flag=n-1;
if(flag-m<0)
flag=flag+n-m;
else
flag=flag-m;
while(flag!=(n-1)){
if(flag+m>n-1)
num[flag+m-n]=num[flag];
else
num[flag+m]=num[flag];
if(flag-m<0)
flag=flag+n-m;
else
flag=flag-m;
}
if(flag+m>n-1)
num[flag+m-n]=temp;
else
num[flag+m]=temp;
}
}
3.测试
#include<iostream>
using namespace std;
int main()
{
int n,m;
cin>>n>>m;
m=m%n;
int num[n]={0};
for(int i=0;i<n;i++){
cin>>num[i];
}
move_1(n,m,num);//更改此处测试方法一二三
for(int i=0;i<n;i++){
cout<<num[i];
if(i!=n-1)
cout<<' ';
}
}