matlab课程告一段落了,开个专栏记录一些有意思的题目。
题目
如下面的红色元素为该矩阵(a)的最外层元素,逆时针旋转一个位置后,矩阵变为(b); 逆时针旋转两个位置后,矩阵变为©;顺时针旋转一个位置后,矩阵变为(d);顺时针旋转一个位置后,矩阵变为(e);
第二层、第三层、…、第n层的数字也按同样的方式旋转。
要求函数的输入参数为一个二维矩阵M和整数k,函数返回将矩阵M的每层元素旋转k个位置后的矩阵;k为正时表示逆时针旋转,k为负时表示顺时针旋转,k=0表示不旋转;要求k的默认值为1。
思路
旋转的是矩阵里一圈圈的元素,那就先找最外层元素旋转的规律。里圈的数据肯定也适用。
假设矩阵为M,我发现无论M矩车的大小是多少,它的一圈元素排列成一维矩车后,每一层都可以划分为四种规律的数据(即下面的红、橙、绿。紫)。
若输入矩阵M为4x4,每一圈的数据从第一行第一列(也就是11位置)开始,按顺时针方向分别为:
11,12,13,14,24,34,44,43,42,41,31,21(最外层)
22,23,33,32(次外层)
若输入矩阵M为5x5,按顺时针方向,位置分别为:
11,12,13,14,15,25,35,45,55,54,53,52,51,41,31,21(最外层)
22,23,24,34,44,43,42,32(次外层)
33(最里层不参与旋转,不考虑)
首先看一下红色的数据,最外层的红色区域的数据可以表示成M(1,1:m-1),次外层红色区域M(2:m-2),因此,所有层的红色区域可以表示为M(i,i:m-i)。
同理,橘色区域表示成M(1:m-i,n+1-1)’。绿色区域可以表示为f1iplr(M(m+1-i,i+1:m+1-i))。紫色区域表示为fliplr(M(i+1:m+1-i,i))。按此规律获得矩阵的一圈圈数列。再利用circshift数将每一圈数列移动k个位置。最后将移动后的数列排列生成原来大小的数组。
代码:
运行结果:
1.k=0,不旋转
2.k=1,逆时针旋转一个位置
3.k=-1,顺时针旋转一个位置
4,k=16,旋转回原位置
结果很完美。