程式設計的技巧經過了幾十年的演進,一路從機械碼、組合語言進入了高階語言。而高階語言從非結構化走向結構化(structured)、函式導向(function-oriented)和物件導向(object-oriented)。就算是物件導向的語言也從 Smalltalk 發展出 Objective-C,另一支從 Simula 而 C++, Java, C#,成了現在最主流的語言。
在 Java, C# 之上開始有人探索其他設計技巧,其中一種就是剖面導向程式設計(暫譯,aspect-oriented programming)。這種程式是基於原有的程式上面,再加上一些特別的函式,稱為「建議」(advice),在函式被呼叫的時候會觸發這些「建議」,可以做參數檢查、權限判斷或最佳化等操作。
許多支援剖面導向的編譯器在實作上會幫被加上「建議」的函式加上一些隱藏的參數。在大部份的情況下是沒有問題的,可是當程式裡有遞迴,或者多個函式互相呼叫時就可能出現問題。幸好只要仔細考慮各種可能性,這些都是可以解決的,比較令人頭痛的是因為加入的「建議」會呼叫已有的函式而新造出遞迴呼叫。目前大家採用的解決辦法很簡單:拒絕這樣的程式。請你幫忙檢查使用者寫出來的程式是否有這種情況。
使用者的程式是由一些函式和「建議」所組成的。每個函式和「建議」裡可能會呼叫別的函式。如果有可能從函式 f 呼叫 g 再呼叫 h 然後又呼叫到 f 則構成一個遞迴。
輸入檔中有多組輸入,每組輸入是一個程式,包含許多行,每一行定義一個函式或「建議」,最多一百行,以一行五個等號「=====」結束。空的程式(一行都沒有)表示檔案結束,不需對這個程式輸出。
每一行定義將以「function」或「advice」開頭,分別表示定義的是函式或「建議」。後面接著函式名或「建議」名,由英文大小寫字母和數字構成,最多二十個字。定義函式的格式為:
function func-name calls called-func-list 例:function f calls g h 函式 f 會呼叫g 和 h |
定義「建議」的格式為:
advice adv-name on advised-func calls called-func-list 例:advice n on f calls g h 建議 n 會在函式 f 被呼叫時被觸發,並會呼叫 g 和 h |
會呼叫的函式列表是以空白格開,最多列十個函數,並且一定都有定義。「建議」不會被直接呼叫,也不會被加上「建議」。函式名與「建議」名都是唯一的,不會重複定義。
對每個程式輸出「Accept」或「Reject」,表示接受輸入的程式或拒絕。
第一組輸入中有 g 呼叫 h 呼叫 g 的遞迴,加入 n 不會增加遞迴。
第二組輸入中原先只有 f 本身的遞迴,加入 n1 和 n2 會有 f 觸發 n1 呼叫 g 呼叫 h 觸發 n2 呼叫 f 的遞迴。
第三組輸入中雖然原先就有 f 本身的遞迴,但加入 nn 造成了新的 f 觸發 nn 呼叫 f 的遞迴。
(Tmt補註:"Accept"不可以拼成"Accetp"喔,要不然會WA。:p)
※2009/01/30輸入說明更新by tmt:感謝suhorng。
2024/07/24 Update by FHVirus:「新造出遞迴呼叫」可以理解為有建議會在呼叫數個函式後觸發自己。
原TIOJ1104 / NPSC2006決賽(prob G)
No. | Testdata Range | Score |
---|---|---|
1 | 0 | 100 |