# 二維陣列 ## MDCPP語法班 12/27 --- ## 複習一下吧! - 一維陣列 ---- - 想開一個能存整數的陣列? - 長度為5? - 名稱叫starburst_stream? ```graphviz digraph structs { node[shape=record] label="starburst_stream" struct1 [label="<f0> 4|<f1> 8|<f2> 7|<f3> 6|<f4> 3"]; } ``` ---- - 如果只是空的陣列 ```cpp=1 #include<bits/stdc++.h> using namespace std; int main(){ int starburst_stream[5]; //陣列開多長 中括號裡就寫多少 ... ``` ```graphviz digraph structs { node[shape=record] label="starburst_stream" struct1 [label="<f0> |<f1> |<f2> |<f3> |<f4> "]; } ``` ---- - 順便把值丟進陣列 ```cpp=4 int starburst_stream[5] = {4, 8, 7, 6, 3}; ``` ```graphviz digraph structs { node[shape=record] label="starburst_stream" struct1 [label="<f0> 4|<f1> 8|<f2> 7|<f3> 6|<f4> 3"]; } ``` ---- ### 存取 ---- - 好比說要把檔案歸位 - 我們需要知道檔案櫃的「位置」 - 在程式,我們叫它**索引值** ---- - 一個長度為5的陣列,索引值(index)如下 ```graphviz digraph structs { node[shape=record] label="0 1 2 3 4" struct1 [label="<f0> |<f1> |<f2> |<f3> |<f4> "]; } ``` ---- - 注意索引值由0開始 ! ```graphviz digraph structs { node[shape=record] label="0 1 2 3 4" struct1 [label="<f0> |<f1> |<f2> |<f3> |<f4> "]; } ``` ---- - 一個長度為5的陣列有五格 - 分別為a[0], a[1], ..., a[4] - 沒有a[5]這一格 ! ---- - 存(賦值) - 可以覆蓋過原先的值 ```cpp=5 starburst_stream[0] = 4; ``` ```graphviz digraph structs { node[shape=record] label="0 1 2 3 4" struct1 [label="<f0> 4|<f1> |<f2> |<f3> |<f4> "]; } ``` ---- - 取(讀取) ```cpp=6 int number = starburst_stream[0]; cout << "輸出number變數= " << number << endl; cout << "也可以直接輸出"; cout << "starburst_stream[0]= " << starburst_stream[0]; ``` ![](https://i.imgur.com/cZ67L8W.png) ---- - 小練習 [A006 最後倒數](http://mdcpp.mingdao.edu.tw/problem/A006) ---- ```cpp=1 //AC code #include <iostream> using namespace std; int main(){ int n; cin >> n; int arr[n]; for(int i = 0; i < n; i++)cin >> arr[i]; //輸入陣列 for(int i = n-1; i >= 0; i--)cout << arr[i] << " "; //倒過來輸出 } ``` --- ### 進入正題! --- ## 二維陣列 ---- - 小提醒 - 跟一維一樣 - 第一格是a[0][0]喔 ---- - 先看看上禮拜的這題 [A025 BINGO LV1](http://mdcpp.mingdao.edu.tw/problem/A025) ---- - 用一維陣列寫? ```cpp=1 //AC code #include <iostream> using namespace std; int main(){ int row1[3], row2[3], row3[3]; for (int i = 0; i < 3; i++) cin >> row1[i] >> row2[i] >> row3[i]; for (int i = 0; i < 3; i++){ cout << row1[i] << " " << row2[i] << " " << row3[i] << endl; } } ``` ```graphviz digraph structs { node[shape=record] label="row1" struct1 [label="1|4|7"]; rankdir=LR } ``` ```graphviz digraph structs { node[shape=record] label="row2" struct1 [label="2|5|8"]; rankdir=LR } ``` ```graphviz digraph structs { node[shape=record] label="row3" struct1 [label="3|6|9"]; rankdir=LR } ``` ---- - 要開三個一維陣列,好像有點累 ---- - 如果今天的bingo盤是5 x 5呢? - 100 x 100呢? ---- - 二維陣列 ! ```cpp=1 //AC code #include<iostream> using namespace std; int main() { int a[3][3]; for(int i = 0; i < 3; i++) for(int j = 0; j < 3; j++) cin >> a[i][j]; for(int i = 0; i < 3; i++) for(int j = 0; j < 3; j++){ cout << a[i][j]; if(j==2)cout << endl; else cout << " "; } } ``` ```graphviz digraph structs { node[shape=record] struct3 [label="{1|4|7}|{2|5|8}|{3|6|9}"]; } ``` ---- - 繼續練習,熟練二維陣列吧 ! ---- - BINGO系列 [A026 LV2 (題目指定N x N)](http://mdcpp.mingdao.edu.tw/problem/A026) [A027 LV3 (判斷有無bingo)](http://mdcpp.mingdao.edu.tw/problem/A027) [A028 LV4 (模擬雙人比賽)](http://mdcpp.mingdao.edu.tw/problem/A028) --- ### 一些應用題解說 ---- [A030 簡單運算LV2](http://mdcpp.mingdao.edu.tw/problem/A030) ---- 給你N和M 再給你N x M的二維陣列 請你把第一排的數加到第二排 再把第二排的數加到第三排 以此類推 ---- - 照步驟慢慢處理 ! ---- - 先把陣列輸入進去 ```cpp=5 ... int n, m; cin >> n >> m; int a[n][m]; for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) cin >> a[i][j]; ``` ---- - 把上排的數加到下排 ```cpp=13 for(int i = 1; i < n; i++) //從第二排開始 一次處理一個橫排 for(int j = 0; j < m; j++) a[i][j] = a[i][j] + a[i-1][j]; //加上前一橫排的值 ``` ---- - 輸出答案 ! ```cpp=18 for(int i = 0; i < n; i++){ for(int j = 0; j < m; j++) cout << a[i][j] << " "; cout << endl; } ... ``` ---- - 小技巧:大括號 ```cpp=1 //AC code #include<iostream> using namespace std; int main() { int n, m; cin >> n >> m; int a[n][m]; for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) cin >> a[i][j]; //從第二排開始 一次處理一個橫排 for(int i = 1; i < n; i++) for(int j = 0; j < m; j++) //加上前一橫排的值 a[i][j] = a[i][j] + a[i-1][j]; for(int i = 0; i < n; i++){ for(int j = 0; j < m; j++) cout << a[i][j] << " "; cout << endl; } } ``` ---- [A032 矩陣翻轉](http://mdcpp.mingdao.edu.tw/problem/A032) ---- ![](https://i.imgur.com/tDTEbUf.png) 請你輸出翻轉後的矩陣 ---- - 想法1:開兩個二維陣列 - 一個M x N 一個N x M ```cpp=5 ... int n, m; cin >> n >> m; int a1[n][m], a2[m][n]; for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) cin >> a1[i][j]; ``` ---- - 把a1翻轉複製到a2 ```cpp=12 for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) a2[j][i] = a1[i][j]; //行列互換 ``` ---- - 再把a2輸出 ```cpp=16 for(int j = 0; j < m; j++){ for(int i = 0; i < n; i++) cout << a2[j][i] << " "; cout << endl; } ... ``` 就解決這題ㄌ ---- - 想法二:乾脆不複製 ---- 我們來觀察一下剛剛的程式碼 ---- ```cpp=12 for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) a2[j][i] = a1[i][j]; //行列互換 for(int j = 0; j < m; j++){ for(int i = 0; i < n; i++) cout << a2[j][i] << " "; cout << endl; } ``` ---- - a2[ j ][ i ]根本就是a1[ i ][ j ] ! - 我們來縮短程式碼吧 ! ---- ```cpp= //AC code #include<iostream> using namespace std; int main() { int n, m; cin >> n >> m; int a1[n][m]; for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) cin >> a1[i][j]; for(int j = 0; j < m; j++){ for(int i = 0; i < n; i++) cout << a1[i][j] << " "; cout << endl; } } ``` ---- ### 好處 - 簡潔、漂亮 - 節省記憶體 - 不用打那麼多字 ---- ### 壞處 - 不直觀(因人而異) - 容易寫錯 --- End...? ###### tags: `MDCPP` `Cosmos`
{"metaMigratedAt":"2023-06-16T16:57:27.484Z","metaMigratedFrom":"Content","title":"二維陣列","breaks":true,"contributors":"[{\"id\":\"1da968a8-fcc6-45a7-b06e-e833f464e623\",\"add\":7490,\"del\":1206}]"}
    365 views
   Owned this note