**考量有些同學本週還在期中考模式, 這週仍是給輕鬆的.. 就.. 測試並研究範例, 然後寫心得。 P.S:前一題萬年曆還沒做好的請繼續完成! Purpose: (1)了解如何量測你的程式可以跑多快? 之前介紹過 time( ) 這會引起Y2K38 problem 的系統函數, 它是被宣告在 <time.h> 內! 其實, 程式員必須還要知道: <time.h> 中還有宣告一些與時間速度等相關的函數與符號常數。 (2)了解 Recursive 程式有多慢? (Loop 比較快!) 研究若 Recursive 函數很慢要如何解決? 例如 recursive 的 Fibonacci 很慢, 有何替代方案? 請參考範例 fibLoop.c 註: 這裡用 array (table) 把以前算過的答案記起來, 算是一種 Dynamic programming (請用 gogle.com 查看) Description: 現在大部分同學已經可以寫出大部份的程式, 可是除了寫得好看外, 也要考慮方法(Algorithm; 演算法)是否恰當? 是否執行起來夠快? 這次就用Fibonacci的兔子問題來研究 clock() 這函數的用法, 注意clock() 這函數它是以 tick (滴答)為單位, 可是.. tick 是啥? 一個 tick 是多久呢? 不一定!!!但可在<time.h>找到答案。 (a)找出 TC++, Dev-CPP, MSVC 或其他的 C/C++ 之 include 目錄下, (也找學長幫忙看看 FreeBSD 和 Linux 上的 gcc/g++ ) 對以下這兩個 Symbolic constant 的 #define 是 多少: CLK_TCK, CLOCKS_PER_SEC 然後把各版本的值列比較表, post 到 e3.nctu 上本題的討論區。 (演習課時可以舉手請助教幫忙連到 FreeBSD/Linux工作站看看 :) (b)測試並研究 fibRec.c, 和fibLoop.c 程式, 然後寫心得潑到 討論區 上。 **注意: 還不太懂 Fibonacci Rabbits problem 的請先上網查詢。 (c)在你自己的電腦與學校電腦測試 clockFib.c 這程式, 注意會測試很久喔! 我們在主程式用了個小技巧讓它測很多想測的 n 值! 記得要把測試心得寫到 e3.nctu 上。 **注意也研究 clockFib.c 內的 #ifdef 與 #ifndef 寫 *** 附件夾檔: fibRec.c, fibLoop.c, clockFib.c 補充說明: *** Recursive 真的很好用 : 想完就寫好了 ! 例如: -- GCD(m, n): 若 n 是 0 阿答案就是 m , 否則 .. 請 .. 你告訴我 GCD(n, m%n); 阿那就是你要的答案 :-) -- hanoi(n, ...): 你先幫我把 n-1 個搬到別處, 我自己搬最底下一個, 你再幫忙我把別處的 n-1個搬到目的地! -- Factorial(n) : 你告訴我 (n-1)階乘, 我叫告訴你 n 階乘 ! -- Fibonacci 費氏數列: ***告訴我 n-1 和 n-2 個月的兔子各有幾對, *** 我就告訴你第 n 個月有幾對的兔子 : long long fib(int n) { // 注意你的編譯器不一定可用long long if(n < 0) return 0; // 以前沒有兔子 if(n==0 || n==1) return 1; // 第 0 個月和第 1 個月 return fib(n-1) + fib(n-2); } ***Recursive 真的是很簡單, 也真的是想完就寫完了! 可是, 當 n 稍微大一些, 就會做很久 ! 例如, fib(55) 可能就要算很久 ! Why? 因為算 fib(55)就要先算 fib(54) 與 fib(53), 阿算 fib(54) 又要算 fib(53) 與 fib(52), ... *** 要如何量測程式的執行時間 (running time) 呢? time(0)傳回的是從 1970/01/01 00:00:00 到現在幾秒, 也就是誤差會大到一秒, 所以 time( ) 顯然不夠用! 因差一秒就差很多了! 尤其是只有做很短時間的! 那要怎辦呢? 阿當然可以故意用 Loop 做很多次量出後再除以 Loop 次數, 可是.. .. 其實, 最好 改用 clock( ) 啦, 若時間實在太短, 也是可用 Loop 跑很多次且用 clock( ) 量, 或是, 有些系統有更準的 function 如 nanotime( ) 等, 自己找看看! 須注意 long clock( ) 傳回的是以 tick(滴答) 為單位! 如何換算成秒 ? *** TC++ 沒有 long long *** long long 有些用 %lld 但有些用 %I64d (Dev-Cpp 或說 MINGW32) 注意也研究 clockFib.c 內的 #ifdef 與 #ifndef 寫法! 不懂就舉手找助教過來問! *** 下週預告: Sorting, 還有, 量測各種 sorting 的快慢 ! 請先用 http://gogle.com 查 "sorting"