# 程式設計(二) Lab 3 講解 ###### tags: `lion_1082` ## lab3 A 部分 ### 題目說明 > 根據從 `file.in` 讀入的資料,將最重的 5 隻牛的體重加總起來輸出 ### 使用 [fstream](http://cplusplus.com/reference/fstream/fstream/) 1. 使用前需要在原始碼的上方加上 `#include <fstream>` 2. 利用 `constructor` 進行開檔或是利用 `member function` 的形式開啟檔案 `open` 函式的[參數形式](http://cplusplus.com/reference/fstream/fstream/open/)是 `open(filename, open_mode)` 常見的開啟模式有以下幾種: - `ios::in` : 以讀取模式開啟檔案 - `ios::out` : 以寫入模式開啟檔案 - `ios::app` : 以寫入模式開啟檔案並將寫入指針移動到檔案結尾處 詳細的模式說明可以參考 [ios_base::openmode - C++ Reference](http://cplusplus.com/reference/ios/ios_base/openmode/) ### 如何讀取檔案? 如同使用 `cin` 與 `cout` 一樣 - 如果你是以 `ios::in` 開啟檔案的話,可以把你所宣告的 fstream 變數當作 `cin` 來讀入資料 ```cpp #include <iostream> #include <fstream> using namespace std; int main() { fstream ff; // 宣告 fstream 變數 int b; ff.open('input.txt', ios::in); // 利用 open 函式開啟檔案 ff >> b; // 從 ff 讀入資料至 b 變數 cout << b << endl; ff.close(); // 關閉檔案 return 0; } ``` ### [vector](http://www.cplusplus.com/reference/vector/vector/) 使用 簡單來說, vector 可以說是 array 的進化版 在 C++ 中,有提供許多好用的 [STL](https://www.runoob.com/cplusplus/cpp-stl-tutorial.html) ,而 Vector 就是其中一個 [STL](https://www.runoob.com/cplusplus/cpp-stl-tutorial.html) #### 使用方法 - 須將 `#include <vector>` 加入程式碼中 - 宣告的時候要告訴編譯器這個 Vector 所要儲存的**元素的資料型態** - 使用 `push_back` 將元素加入 Vector - 可以使用 `[]` 或是 `at()` 這個成員函式來存取其中的特定元素 - 使用 `size()` 取得 Vector 的大小 ```cpp #include <iostream> #include <vector> using namespace std; int main() { vector <int> aa; // 在 < > 中告知元素的資料型態 for (int i = 0; i < 10; i++) { aa.push_back(i); // 將變數 i 的數值存進 aa 中 } // now 0 ~ 9 are in the vector named `aa` cout << aa[3] << endl; // output: 3 cout << aa.at(3) << endl; // output: 3 cout << aa.size() << endl; // output: 10 return 0; } ``` ### [sort](http://www.cplusplus.com/reference/algorithm/sort/) 使用 - 要將 `#include <algorithm>` 加進程式碼裡 - `sort` 函式的[參數結構](http://www.cplusplus.com/reference/algorithm/sort/) : `sort(begin_pointer, end_pointer, function_pointer)` - `sort` 可以根據你所提供的 function 來改變排序的方式 - `sort` 可以使用在許多的資料型態上(如 array, vector, string 等等) ```cpp #include <iostream> #include <algorithm> #include <vector> using namespace std; int main() { vector <int> aa; aa.push_back(0); aa.push_back(3); aa.push_back(2); aa.push_back(5); // now aa is [0, 3, 2, 5] sort(aa.begin(), aa.end()); // the result is [0, 2, 3, 5] return 0; } ``` 搭配傳入比較函數可以做不同的變化 ```cpp #include <iostream> #include <algorithm> #include <vector> using namespace std; // 定義比較函式 bool cmp(const int a, const int b) { return a > b; } int main() { vector <int> aa; aa.push_back(0); aa.push_back(3); aa.push_back(2); aa.push_back(5); // 利用比較函式更動排序 sort(aa.begin(), aa.end(), cmp); // now the result is [5, 3, 2, 0] return 0; } ``` ### [範例程式碼 (A 部分)](https://github.com/OscarShiang/pd2_lab3/blob/master/lab3_a.cpp) ## lab3 B 部分 ### 題目說明 > 執行 `Vector and Array` 投影片第 21 與 22 頁的程式碼,並依照結果分析 $O(n^2)$ 與 $O(n\ log\ n)$ 的差異 ### 時間複雜度 根據[維基百科](https://en.wikipedia.org/wiki/Time_complexity)的敘述: > 在電腦科學中,演算法的時間複雜度(Time complexity)是一個函式,它定性描述該演算法的執行時間。 > [color= purple] ### [Insertion sort](https://en.wikipedia.org/wiki/Insertion_sort) 與我們日常生活中排撲克牌的方法類似,時間複雜度為 $O(n^2)$ ![](https://upload.wikimedia.org/wikipedia/commons/0/0f/Insertion-sort-example-300px.gif) ### [sort()](https://en.wikipedia.org/wiki/Sort_(C%2B%2B)) 未有統一的實作方法,依照編譯器的不同可能有不同的實作方式 但在 C++11/14 標準裡有規範其時間複雜度為 $O(n\ log\ n)$ ### 執行結果 利用測量得到的執行時間畫出下圖: ![](https://hackmd.io/_uploads/B1kNB7r4n.png) 可以看到 [insertion sort](https://zh.wikipedia.org/zh-tw/插入排序) 在元素越來越多的時候,其所花費時間的上升曲線會比使用 sort 函式還來得陡,這是因為 [insertion sort](https://zh.wikipedia.org/zh-tw/插入排序) 在時間複雜度上屬於 $O(n^2)$ 而 sort 函式根據 C++11/14 的標準,時間複雜度為 $O(n\ log\ n)$ ,所以兩者在排序數量漸增時所需花費時間的差異就會逐漸顯現出來。 ### [範例程式碼 (B 部分)](https://github.com/OscarShiang/pd2_lab3/blob/master/lab3_b.cpp)