**考量有些同學本週還在期中考模式, 這週仍是給輕鬆的..
就.. 測試並研究範例, 然後寫心得。
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"