陣列的認識與使用 陣列是由具有相同型態的變數集合成的 陣列的每個資料稱為元素(element),元 素儲存在記憶體連續的位置上 透過索引 ( index) 可存取陣列的元素 陣列的意義 1. 陣列輸入 for (i = 0; i < 200; i++) cin >> a[i]; 2. 陣列輸出 for (i = 0; i < 200; i++) cout << a[i] << " "; 3. 陣列加總 sum = 0; for (i = 0; i < 200; i++) sum += a[i]; 陣列的宣告 格式 資料型態 陣列名稱[大小]; 資料型態:int, long, char, float, double 等 陣列名稱必須是識別字 例如宣告一個大小為 6 的整數陣列 a int a[6]; int n = 6; int a[n]; 陣列的宣告 int a[6]; • a 是陣列名稱,有 6 個元素 ,可存放 6 個 整數 a[0], a[1], ⋯⋯ a[4], a[5] • 陣列索引為 0 ~ 5 第一個元素是 a[0],不是 a[1] 最後一個元素是 a[5],不是 a[6] 第 i 個元素是 a[i - 1] • 陣列記憶體大小依宣告的資料型態和陣列 大小而定 陣列 a 儲存整數,每個元素占 4 bytes,6 個元素,陣列 a 占 24 bytes 陣列的宣告 1. 2. 3. 陣列名稱 = 陣列記憶體起始位址 索引是相對陣列起始位址的位移量(offset), 指從第一個元素開始的第幾個 例如 a[3] 位移量3,表示 a[3] 是從第 1 個元素開始的第 3 個元素 編譯器不會檢查索引是否超出範圍,也 不會出現錯誤,但執行結果是錯的 陣列初始化 陣列在函數內宣告,元素值可能是不可 預知的資料 初始化是使用陣列前,賦予元素特定的 資料值 陣列未被初始化,不會編譯錯誤,但會 得到錯誤結果,增加除錯難度 陣列初始化 1. 使用 for 迴圈 2. 指定資料值給陣列元素 3. 給予全部元素初始值 初始值個數不能比元素多 陣列初始化 4. 5. 給予部分元素初始值,未設定的元素會 被設為 0 給予全部元素初始值 0 int a[5] = { }; // int a[5] = {0, 0, 0, 0, 0} 陣列初始化 6. 不指定陣列大小,直接給予初始值 int a[ ] = {10, 11, 12, 13, 14}; 有 5 個初始值,編譯器會將陣列大小視 為 5,等同 int a[5] int a[ ]; 是錯的語法 使用 { } 初始化時,須在宣告時就進行, 否則會產生錯誤 陣列的操作 透過索引存取元素,索引值必須是整數 陣列的操作 陣列名稱與陣列元素的不同 陣列名稱是記憶體位址, 無法只用名稱存取陣列內的資料 x cin >> a; cout << a; x 陣列元素 存放陣列的資料,用索引可存取陣列內 的資料 輸入或輸出陣列資料時,需一個一個元 素輸入或輸出 陣列的操作 1. 複製 int a[10], b[10]; b = a; b = a → 將陣列 a 的起始位址指定給陣列 b 的起始位址 → a, b 陣列會有相同的起始位 址 →同一個陣列 陣列複製需用迴圈,逐一複製每個元素 陣列的操作 2. 比較 不可以直接使用陣列名稱比較 int i, a[10], b[10]; if (b != a) 要每個元素逐一比較 陣列的操作 3. 相加 大小相同的陣列才能相加 陣列 a 與 b 相加到陣列 c,不能用 c = a + b; 必須逐一元素相加 二維陣列與多維陣列 二維陣列的宣告 多個相同資料型態的變數, 可組成一維陣列 多個相同型態與大小的一維陣列, 可組成二維陣列 二維陣列的宣告 6 位同學 5 學科成績,可使用 6 個一維 陣列 a ~ e,每個陣列有 5 個元素來儲存 表格式資料使用二維陣列表示,可以使 用 for 雙重迴圈進行處理,非常方便 二維陣列的宣告 宣告的格式 資料型態 陣列名稱[列大小][行大小]; 例如 二維陣列的宣告 一個 m × n (m 列 n 行) 的二維陣列, 第 i 列第 j 行的元素是 a[i-1][j-1], 其中 i 是 0 ~ m - 1,j 是 0 ~ n - 1 二維陣列的宣告 編譯器提供連續的記憶體位置來儲存二 維陣列元素 例如 3 × 4 的二維陣列,會用 12 個連續 的位置來存放元素 存放的順序是先存第一列的元素,再存 第二列的元素,依此類推 二維陣列的宣告 二維陣列本質上是一維陣列 使用一維陣列,也可以達到多維陣列的 功能 int a[3][4]; int a[12]; 實務上,很少用到三維以上的陣列 二維陣列的初始化 分列給予二維陣列初始值 將所有初始值放在大括弧內 給予部分元素初始值,未設定初始值的 元素會被設為 0 二維陣列的初始化 可省略列或行的大小 不能同時省略行列的大小,因為編譯器 會無法確定陣列的形式 二維陣列 處理二維陣列可使用 for 雙重迴圈, 外迴圈控制列索引,內迴圈控制行索引 例如:輸出陣列 a 元素值的程式如下: int a[5][3]; for(int i=0;i<5;i+=1) for (int j=0;j<3;j+=1) cout << a[i][j] << endl; 二維陣列 此陣列 a 每列執行完後,會接到下一列開 頭繼續執行,例如: a[0][2] 後面是 a[1][0]; a[1][2] 後面是 a[2][0], 依此類推,最後是 a[4][2] C++ STL Standard Template Library https://zh.wikipedia.org/wiki/標準模板庫 提供各種「容器」 • 容器即為資料結構的ADT實作 Python V.S. C++ STL list V.S. vector/array/list/deque dictionary V.S. map/unordered_map tuple V.S pair/tuple set V.S. set 類似陣列的資料結構 Array 陣列的封裝 https://en.cppreference.com/w/cpp/container/array List Linked-list(利用指標連結前後元素) 搜尋速度慢,但能快速插入刪除元素 https://en.cppreference.com/w/cpp/container/list Deque double-ended queue 能快速新增到開頭結尾,但跌代器會受到影響 https://en.cppreference.com/w/cpp/container/deque 類似陣列的資料結構 Vector https://en.cppreference.com/w/cpp/containe r/vector 只能存放單一資料型態 Vectort常用成員函式 v表示vector變數 v.size() v.empty() 回傳vector內元素個數 回傳vector是否為空(v.size()==0) v.at(index) 類似python list.index(index) 安全取得index的值 v.front()/v.back() 取得第一個/最後一個值 Vectort常用成員函式 v.push_back(value) 等同python list.append(value) 將value新增到容器結尾 v.pop_back() v.clear() 取出最後一個元素 清空vector v.resize(n)/v.resize(n, x) 將vector的size調整為n 若沒有定義x預設初始為0 vector與迴圈 迭代器(Iterator) 用於容器內部遍歷的物件 定位內部物件「位置」 以vector為例 開頭位置:v.begin() 結尾位置:v.end() 從開頭往後3個:v.begin()+3 取得值: • *v.begin() • *(v.begin()+3) 利用迭代器控制vector reverse(v.begin(),v.end()) 類似python list.reverse() 倒轉v的元素 sort (v.begin(),v.end()) 類似python list.sort() 排序v的元素 v.insert(v.begin()+index, n) 類似python list.insert(index, n) 將n插入到index的位置 v.erase(v.begin()+index) 刪除index位置的元素 練習題 練習題 c067: Box of Bricks 練習題 b139. NOIP2005 2.校门外的树 練習題 a034-二進位制轉換 練習題 a216: 數數愛明明 練習題 a015-矩陣的翻轉 二維陣列 練習題 APCS10603第2題小群體 練習題 d984-棄保效應 練習題 d164: 七、最佳选择 練習題 a016: 數獨(SUDOKU) 二維陣列 練習題 APCS10603第3題數字龍捲風 二維陣列 練習題 APCS10510第2題最大和 二維陣列 練習題 c085: Pseudo-Random Numbers 練習題 d097: 10038 - Jolly Jumpers 練習題 d123: acm 11063 B2-Sequence 練習題 d471-0與1的遊戲 練習題 d635: 幸運777?luck 練習題 挑戰題 d166: 反轉表 挑戰題 d562-山寨版磁力蜈蚣 挑戰題 a225: 明明愛排列 挑戰題 c069-2- What Day Is It?-ACM-602 練習題 c084: Expanding Fractions 求循環小數 練習題 d044: acm 640 - Self Numbers 練習題 b130: NOIP2006 1.明明的随机数 練習題 c061: Binomial Showdown 求組合數 練習題 d134: acm-369: Combinations求組合數 練習題 d985: Gran Turismo 5 陣列求平均 練習題 d673: acm 11608 - No Problem 練習題 a240. 第一題:1 / 17 小數第 n 位 求1/17小數點以下n位的 值與總和 練習題 d223-acm-10137 The Trip 練習題 c135-acm-706: LCD-Display 練習題 10050-Hartals 模擬罷工時間,星期五與星期六不罷工 練習題 練習題 d213: 长寿的兔子 練習題 a248: 新手訓練 ~ 陣列應用 無窮位數小數 練習題 a291: problem 允許重複數字的nAnB 練習題 acm 340 Master-Mind Hints nAnB問題 練習題 a414: 位元運算之進位篇 十進位轉二進位 加1 問進位個數 練習題 a417: 螺旋矩陣 順時針或逆時針將數字填入方陣 練習題 d478: 共同的數 - 簡易版 比較兩已排序個別數字不重複數 列,相同的數共有幾個 練習題 a693: 吞食天地 練習題 uva11040 - Add bricks in the wall二維陣列,最底層 a[9][2]=(a[7][1]-a[9][1]-a[9][3])/2 挑戰題 103北市賽 水晶球