数组循环右移最全的两种方法2021/5/6

一个数组A中存有N(>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(≥0)个位置,即将A中的数据由(A​0​​A​1​​⋯A​N−1​​)变换为(A​N−M​​⋯A​N−1​​A​0​​A​1​​⋯A​N−M−1​​)(最后M个数循环移至最前面的M个位置)。如果需要考虑程序移动数据的次数尽量少,要如何设计移动的方法?

输入格式:

每个输入包含一个测试用例,第1行输入N(1≤N≤100)和M(≥0);第2行输入N个整数,之间用空格分隔。

输出格式:

在一行中输出循环右移M位以后的整数序列,之间用空格分隔,序列结尾不能有多余空格。

输入样例:

6 2
1 2 3 4 5 6

输出样例:

5 6 1 2 3 4

 方法一(无脑移动法):

思路从数组的最后一位开始每次移动1位,共移动m位

缺点:移动次数太多

#include<stdio.h>
void main(){
	int n,m,i,t;
	int a[101];
	scanf("%d %d",&n,&m);
	
	for(i=0;i<n;i++)
		scanf("%d",&a[i]);
		
		
	while(m--){
		t=a[n-1];
		for(i=n-1;i>=1;i--){
			a[i]=a[i-1];
		}
		a[0]=t;
	}
	
	for(i=0;i<n;i++){
		if(i==0)printf("%d",a[i]);
		else printf(" %d",a[i]);
	}
}

 

方法二:(聪明法)

思路:知道要输出的第一位,把从这一位到数组末尾的数全输出,再从头把其他元素输出

#include<stdio.h>
void main(){
	int n,m,i,r;
	int a[101];
	scanf("%d %d",&n,&m);
	for(i=0;i<n;i++)
		scanf("%d",&a[i]);
	if(!m||m%n==0){
		printf("%d",a[0]);
		for(i=1;i<n;i++)
			printf(" %d",a[i]);
	}else {
		r=m%n;
		for(i=n-r;i<n;i++)            //这里是关键n-r是要输出的第一位
			{
				if(i==n-r) printf("%d",a[i]);
				else printf(" %d",a[i]);
			}
		for(i=0;i<n-r;i++)
			printf(" %d",a[i]);
	}
}

 

 

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 数组循环右移是指将数组中的元素向右循环移动k个位置,即将数组最后k个元素移动到数组最前面,而前面的元素则向右移动k个位置。以下是一种加强版的实现方式: ```c #include <stdio.h> void reverse(int arr[], int start, int end) { // 反转数组中指定区间的元素 while (start < end) { int temp = arr[start]; arr[start] = arr[end]; arr[end] = temp; start++; end--; } } void rotate(int arr[], int n, int k) { // 将数组中的元素向右循环移动k个位置 k %= n; // 处理k大于n的情况 reverse(arr, 0, n - 1); // 先反转整个数组 reverse(arr, 0, k - 1); // 再反转前k个元素 reverse(arr, k, n - 1); // 最后反转剩下的元素 } int main() { int arr[] = {1, 2, 3, 4, 5}; int n = sizeof(arr) / sizeof(arr[0]); int k = 2; rotate(arr, n, k); for (int i = 0; i < n; i++) { printf("%d ", arr[i]); } return 0; } ``` 这里使用了一个反转数组的函数`reverse`,先将整个数组反转,然后再反转前k个元素和剩下的元素即可。这种方法的时间复杂度为O(n),空间复杂度为O(1)。 ### 回答2: 数组循环右移加强版C语言是一种将数组中的元素向右循环移动指定位置的操作。循环右移意味着数组中的元素将被向右移动,最后的元素将被移到数组的开头。 下面是一个实现数组循环右移加强版的C语言代码: ```c #include <stdio.h> void rightRotate(int arr[], int n, int k) { int temp[k]; // 保存要移动的元素 for (int i = 0; i < k; i++) { temp[i] = arr[n - k + i]; } // 右移其余元素 for (int i = n - k - 1; i >= 0; i--) { arr[i + k] = arr[i]; } // 将保存的元素添加到数组开头 for (int i = 0; i < k; i++) { arr[i] = temp[i]; } } int main() { int arr[] = {1, 2, 3, 4, 5, 6, 7}; int n = sizeof(arr) / sizeof(arr[0]); int k = 3; rightRotate(arr, n, k); printf("循环右移%d位后的数组:\n", k); for (int i = 0; i < n; i++) { printf("%d ", arr[i]); } printf("\n"); return 0; } ``` 在以上代码中,我们定义了一个函数 `rightRotate()`,它接受一个数组数组长度和要循环右移的位数作为参数。该函数首先创建一个临时数组 `temp`,并将要移动的元素保存在其中。然后,它使用一个循环将其余的元素向右移动,最后将保存的元素添加到数组的开头。在主函数中,我们声明了一个示例数组,并将其长度和要移动的位数传递给 `rightRotate()` 函数进行操作。最后,我们遍历并打印循环右移后的数组。 通过运行以上代码,你将得到如下输出: ``` 循环右移3位后的数组: 5 6 7 1 2 3 4 ``` 以上就是数组循环右移加强版C语言的回答。 ### 回答3: 数组循环右移是一种常见的数组操作,即将数组中的元素向右移动k个位置,超出数组边界的元素将移到数组的开头位置。如何实现数组循环右移的加强版C语言呢? 首先,我们需要定义一个函数来实现数组循环右移的功能。函数的输入参数包括数组的指针、数组的长度和右移的位移k。函数的返回值类型可以是void,表示不需要返回修改后的数组。 在函数的内部,我们需要进行一些处理。首先,我们需要对k进行处理,如果k大于数组的长度,我们可以通过取余操作,将其转化为小于数组长度的位移。然后,我们需要定义一个临时数组temp,用来保存右移后的结果。接下来,我们可以使用两个循环来完成右移的操作。 第一个循环用来将原数组的最后k个元素放入临时数组temp的前k个位置中。我们可以使用一个变量i来表示原数组的下标,从数组长度减去k开始,递减到数组长度减1,同时使用另一个变量j来表示临时数组的下标,从0递增到k-1,在每一次迭代中,将原数组中对应下标的元素赋值给临时数组中的对应位置。 第二个循环用来将原数组中前n-k个元素放入临时数组temp的第k个位置之后的位置中。我们可以使用一个变量i来表示原数组的下标,从0递增到数组长度减k-1,同时使用另一个变量j来表示临时数组的下标,从k递增到数组长度-1,在每一次迭代中,将原数组中对应下标的元素赋值给临时数组中的对应位置。 完成两个循环后,我们将临时数组中的所有元素逐个赋值给原数组即可。这样,我们就完成了数组循环右移操作。 总结起来,数组循环右移加强版C语言的实现包括对位移k的处理和两个循环的使用。通过这种方式,我们可以轻松地实现数组循环右移功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值