MATLAB一个递归实例

MATLAB一个递归实例

昨天在MATLAB中文论坛上见到的一个小题目,很适合用递归来解决。


题目描述

输入一个方阵,把所有的数按照逆时针方向旋转一个位子。
例如,将矩阵

147258369

转变为
214357698

或者,将矩阵
15913261014371115481216

转变为
21593761341110148121615


解决思路

这道题乍看一下不太好下手,关键原因在于MATLAB的矩阵存储方式要么是以行列为定位基准,要么是按列顺序排列。这个问题要求我们打破行和列的局限,以另一种方式看待矩阵。
将整个矩阵想像成一个洋葱,对于矩阵

147258369

我们可以这样看,忽略掉中心的一个数
14728369

如果这样还不够明显
我们以四阶方阵来看:
15913214315481216

610711

这就是一个“剥洋葱”的过程。也就是说,先假定“逆时针旋转”这件事是一个已知的操作。那么对一个n阶(n>2)方阵来说,对洋葱的每一层,从外而内,它的处理模式都是一致的:
剥下最外层 –> 逆时针旋转 –> 剥剩下部分的最外一层 –> 逆时针旋转 –> ……
在算法的角度上,很容易想到递归的办法。


代码实现

function A = rotate_me(A)
% initial check
[n,m] = size(A);
if n ~= m
    error('Must be a square matrix!');
elseif n == 1 || n == 0 % recursion end condition
    return;
end

% rotation
C = [A(1,1:end) A(2:end,end)' A(end, end-1:-1:1) A(end-1:-1:2,1)'];
C = [C C(1)];
C(1) = [];

A(1,1:end) = C(1:n);
A(2:end,end) = C(n+1:2*n-1)';
A(end,end-1:-1:1) = C(2*n:3*n-2);
A(end-1:-1:2,1) = C(3*n-1:4*n-4)';

%recursion
A(2:end-1,2:end-1) = rotate_me(A(2:end-1,2:end-1));

可以看到,利用MATLAB的矩阵处理特性,可以对外圈元素进行整理,然后通过向队列尾部添加头部元素,再删除头部元素的方式实现循环移动操作,最后再将循环后的矩阵元素回填到相应的位置。
最后将未处理部分进入递归,一直到终止条件,即剩下一个数(奇阶方阵)或一个数不剩(偶阶方阵)。

把上面代码用editor保存成rotate_me.m,运行下面的代码进行实验:

A = 1:9; A = reshape(A,3,3); A = A’;
B = 1:16; B = reshape(B,4,4); B = B’;
C = 1:25; C = reshape(C,5,5); C = C’;
rotate_me(A)

ans =

 2     3     6
 1     5     9
 4     7     8

rotate_me(B)

ans =

 2     3     4     8
 1     7    11    12
 5     6    10    16
 9    13    14    15

rotate_me(C)

ans =

 2     3     4     5    10
 1     8     9    14    15
 6     7    13    19    20
11    12    17    18    25
16    21    22    23    24

你可能感兴趣的:(matlab,递归,MATLAB)