作者:王一哲
第1版:2021年10月21日
第2版:2023年4月9日
第3版:2025年3月28日,補充 C++ 的語法
我們可以利用自訂函式將某一段程式碼取個名字,並設定好它的回傳值,接下來就可以在後續的程式碼中直接呼叫自訂函式,這樣可以使程式碼較為簡潔。自訂函式的語法如下
自訂函式的關鍵字是 def,也就是 define 的前 3 個字母。函式名稱的部分不能使用系統保留字。輸入參數則是在呼叫函式時傳給函式的變數,如果不需要輸入參數時可以什麼都不加。return 之後是函式回傳值,可以沒有回傳值,也可以有多個回傳值,當程式執行完 return 之後就會離開自訂函式。
我們可以用以下的程式碼自訂名為 hello 的函式,這個函式不需要輸入參數,功能就是印出 Hello World!,也沒有回傳值。
如果要在後續的程式中呼叫 hello,寫法為
請注意,hello 後面的 () 不能省略。執行時會輸出
如果用以下方式呼叫
輸出為
補充 C++ 的寫法。
我們可以用以下的程式碼自訂名為 sub 的函式,這個函式需要輸入參數a、b,功能是回傳 a-b 的計算結果。
如果要在後續的程式中呼叫 sub,則輸入參數為 2、3,寫法為
請注意,如果輸入參數不加上名稱時會按照輸入的順序分別傳給 a、b。執行時回傳值皆為
在自訂函式時也可以設定輸入參數的預設值,例如
呼叫 sub 時可以輸入參數,如果沒有輸入參數則會自動採用預設值,例如以下的寫法回傳值為 4。
若改為這個寫法則回傳值為 -1。
如果改成以下的寫法
則回傳值會有 3 個。如果用以下方式呼叫 sub
則 c 的資料類別為元組 (tuple),變數值為
如果想要將回傳值分別指定給變數 d、e、f,寫法為
d、e、f 的變數值分別是 -1、2、3。
補充 C++ 的寫法。
函式的遞迴是指於自訂函式中呼叫自己或是其它自訂函式,如果使用得當可以大幅減少程式碼,但是使用不當會讓使用者很難看出程式碼的運作流程。使用函式的遞迴,一定要留下遞迴出口,在符合條件時能夠離開自訂函式,才不會形成無窮迴圈。以下是3個於自訂函式中呼叫自己的例子。
如果要計算從 1 加到 n 的正整數總合,可以定義以下的函式,將一個 for 迴圈包在裡面,回傳加總的結果。
使用函式遞迴的寫法如下:
若用 代表自訂函式,以 為例,以上的程式碼運作的流程為
但是遞迴的寫法有一個缺點,如果遞迴次數過多、深度太深,程式會停止運作。
補充 C++ 的寫法。
正整數的階乘是指小於、等於此正整數的所有正整數乘積,另外定義0的階乘為1,以下是幾個例子
由以上幾個例子可得
如果想要用 Python 寫出計算 的函式,不使用函式遞迴的寫法如下:
使用函式遞迴的寫法如下:
這個寫法不需要在自訂函式中包進一個 for 迴圈,若用 代表自訂函式,以 為例,運作流程如下:
補充 C++ 的寫法。
若以 表式費波那契數列第 個值,由小到大依序為
若 ,則 。
如果想要用 Python 寫出計算 的函式,不使用函式遞迴的寫法如下:
使用函式遞迴的寫法如下:
這個寫法不需要在自訂函式中包進一個 for 迴圈,而且幾乎就是按照數學定義寫自訂函式內容,反而比不使用函式遞迴的寫法簡單、易懂。
補充 C++ 的寫法,不使用遞迴。
遞迴。
我通常不會這樣寫程式,這會使程式碼難以理解。以下的例子來源為 APCS 105年3月觀念題第14題,再改寫成 Python 格式。
因為代入的數值很大,要先找出運作規律,例如foo(100) = bar(90) = foo(85) 或是 bar(100) = foo(95) = bar(85),如果經過 foo 及 bar 各1次,代入的數值減15,當代入的數值小於、等於20可能會結束遞迴。由於 6693 % 15 = 3,因此 foo(6693) = foo(18) = bar(8),8 <= 10,印出 bar: 8,結束遞迴。原版的題目中有一項是 foo(15106),如果用 Python 程式碼測試時,會遇到遞迴深度過深的問題,無法得到運算結果,但如果改寫成 C++ 程式碼則可以得到運算結果。
有些題目的測資數量很多,會使得遞迴的次數過多、深度太深,程式碼在測試時可能會超時。以 ZeroJudge 基礎題 a216. 數數愛明明 為例,如果按照題目的定義使用函式遞迴,
會寫出以下的程式碼,測試時會超時。
但如果改用 C++,變數格式要使用 long,否則會溢位,使用時間約為 0.5 s,記憶體約為 328 kB,通過測試。
所以遇到遞迴的題目時,可以試著找出一般式。先求 ,列出幾行算式
將以上式子相加可得
接下來求 ,列出幾行算式
將以上式子相加可得
直接將測資指定的 代入一般式,通常會立刻得到答案。以下的 Python 程式碼在 ZeroJudge 測試時,使用時間約為 18 ms,記憶體約為 3.3 MB,通過測試。
以下的 C++ 程式碼在 ZeroJudge 測試時,使用時間約為 2 ms,記憶體約為 328 kB,通過測試。
Python
、C++