概述
MATLAB一个递归实例
昨天在MATLAB中文论坛上见到的一个小题目,很适合用递归来解决。
题目描述
输入一个方阵,把所有的数按照逆时针方向旋转一个位子。
例如,将矩阵
⎡⎣⎢147258369⎤⎦⎥
转变为
⎡⎣⎢214357698⎤⎦⎥
或者,将矩阵
⎡⎣⎢⎢⎢15913261014371115481216⎤⎦⎥⎥⎥
转变为
⎡⎣⎢⎢⎢21593761341110148121615⎤⎦⎥⎥⎥
解决思路
这道题乍看一下不太好下手,关键原因在于MATLAB的矩阵存储方式要么是以行列为定位基准,要么是按列顺序排列。这个问题要求我们打破行和列的局限,以另一种方式看待矩阵。
将整个矩阵想像成一个洋葱,对于矩阵
⎡⎣⎢147258369⎤⎦⎥
我们可以这样看,忽略掉中心的一个数
⎡⎣⎢1472∗8369⎤⎦⎥
如果这样还不够明显
我们以四阶方阵来看:
⎡⎣⎢⎢⎢159132∗∗143∗∗15481216⎤⎦⎥⎥⎥
⎡⎣⎢⎢⎢∗∗∗∗∗610∗∗711∗∗∗∗∗⎤⎦⎥⎥⎥
这就是一个“剥洋葱”的过程。也就是说,先假定“逆时针旋转”这件事是一个已知的操作。那么对一个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一个递归实例的全部内容,希望文章能够帮你解决MATLAB一个递归实例MATLAB一个递归实例所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复