Matlab 教材:遞迴函式

每個 Matlab 函式,不論是內建的、外掛的還是使用者自己寫的, 都可以呼叫別的函式。例如在前一節的 collatz() 裡面, 呼叫了 nargin(), nargout(), disp(), length(), floor()rem()。 其實 nargin()nargout() 並不需要任何參數, 因此使用的時候不需要寫括號。 但是我還是寫 nargin()nargout(), 那一對空括號只是一種書寫的習慣,表示 nargin 和 nargout 是函式而不是變數、也不是保留字。

Matlab 函式不但可以呼叫其他函式,它還可以呼叫自己,而且可以重複呼叫自己。 這種「重複執行一套給定的程序」的流程控制方式, 稱為 遞迴 (recursion)。

例如,若 n 是一個正整數,則 n! (n 階乘) 的迭代定義方式是

n! = 1 * 2 * 3 * ... * n
用 Matlab 正統方法寫,應該是
prod(1:n)
而如果硬要用迴圈,for 迴圈寫法是
fac = 1;
for k=2:n
    fac = fac*k;
end
而 while 迴圈的寫法是
fac = 1;
k = 2;
while (k <= n)
    fac = fac*k;
    k = k+1;
end
其實還有更聰明一點的寫法,但是這些都只是粗淺的例子, 沒必要耍把戲。

其實階乘也有遞迴形式的定義,就是

定義 0! = 1,若 n>0 則定義 n! = n * (n-1)!
如果要用電腦語言實現遞迴形式的定義,就要寫函式, 而且讓那個函式以遞迴的方式重複計算。

fac.m 檔案內寫一個 fac() 函式,如下。

function fn = fac(n)
% Usage: fac(n)
%
% Here n is a nonnegative integer, and fn is n!.  This function doesn't
% validate the input argument.  If n is not an integer, its floor is
% assumed.  If n is negative, 1 is returned.
%
% Shann 2004-05-05

n = floor(n);
if (n > 1)
    fn = n * fac(n-1);
else
    fn = 1;
end

fac() 寫風格與 collatz() 有一處不同: