昨天在matlab中文論壇上見到的乙個小題目,很適合用遞迴來解決。輸入乙個方陣,把所有的數按照逆時針方向旋轉乙個位子。
例如,將矩陣 ⎡⎣
⎢147
2583
69⎤⎦
⎥ 轉變為 ⎡⎣
⎢214
3576
98⎤⎦
⎥ 或者,將矩陣 ⎡⎣
⎢⎢⎢1
59132
610143
711154
81216⎤
⎦⎥⎥⎥
轉變為 ⎡⎣
⎢⎢⎢2
1593
76134
1110148
121615⎤
⎦⎥⎥⎥
這道題乍看一下不太好下手,關鍵原因在於matlab的矩陣儲存方式要麼是以行列為定位基準,要麼是按列順序排列。這個問題要求我們打破行和列的侷限,以另一種方式看待矩陣。
將整個矩陣想像成乙個洋蔥,對於矩陣 ⎡⎣
⎢147
2583
69⎤⎦
⎥ 我們可以這樣看,忽略掉中心的乙個數 ⎡⎣
⎢147
2∗83
69⎤⎦
⎥ 如果這樣還不夠明顯
我們以四階方陣來看: ⎡⎣
⎢⎢⎢1
59132
∗∗143
∗∗154
81216⎤
⎦⎥⎥⎥
⎡⎣⎢⎢⎢∗∗
∗∗∗6
10∗∗7
11∗∗∗
∗∗⎤⎦
⎥⎥⎥
這就是乙個「剝洋蔥」的過程。也就是說,先假定「逆時針旋轉」這件事是乙個已知的操作。那麼對乙個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
乙個遞迴演算法
要求實現1,1,2,3,5,8,13,21,這樣乙個序列。分析一下輸出結果 發現後乙個數字是前2個數字的和。遞迴演算法如下 public static int recursion int i if i 0 return 0 else if i 0 i 2 return 1 else return r...
乙個遞迴問題
created by baicai on 14 5 10.遞迴問題 遞迴中兩個重要的點 1.遞迴公式 2.終止條件 函式的區域性變數存在棧中,可能會棧溢位,所以可以考慮使用全域性陣列,或者動態分配陣列 遊戲問題 類似迷宮求解,自相似性表現在每走一步的探測方式相同,可以用遞迴方法求解,通過列舉出所有從...
PHP遞迴演算法的乙個例項 幫助理解
遞迴函式為自呼叫函式,在函式體內直接或間接自己呼叫自己,但需要設定自呼叫的條件,若滿足條件,則呼叫函式本身,若不滿足則終止本函式的自呼叫,然後把目前流程的主控權交回給上一層函式來執行,可能這樣給大家講解,還是很難明白,直接上例子 function test n else echo n.test 2 ...