# 二維陣列
## 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];
```

----
- 小練習
[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)
----

請你輸出翻轉後的矩陣
----
- 想法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}]"}