### C程式設計導論
### 陣列
---
<!-- .slide: data-transition="fade" -->
<h3 class="text-left">
Table of Contents
</h3>
- 認識陣列
- 一維陣列
- 奇奇怪怪的一維陣列操作
- 二維陣列
- 奇奇怪怪的二維陣列操作
- 例題練習
----
<!-- .slide: data-transition="fade" -->
### 為了節省講義空間
### 從這裡開始會習慣性省略以下幾行程式
```cpp
#include<stdio.h>
int main(){
return 0;
}
```
<!-- .element: class="fragment" data-fragment-index="1" -->
---
### 認識陣列
----
<!-- .slide: data-transition="fade" -->
**在前面的章節 我們學了如何宣告變數**
```cpp
int n, a, b, c;
char s1, s2;
```
----
<!-- .slide: data-transition="fade" -->
**這時可以想個問題**
**如果需要一次處理數以萬計的資料時**
**應該會宣告變數到手軟吧**
<!-- .element: class="fragment" data-fragment-index="1" -->
**就算可以**
**這樣宣告出來的資料也不方便使用**
<!-- .element: class="fragment" data-fragment-index="2" -->
----
<!-- .slide: data-transition="fade" -->
**因此 我們需要一個東西來滿足以下需求**
- **一次宣告多筆資料**
- **方便取用**
**這個東西就是 陣列**
<!-- .element: class="fragment" data-fragment-index="1" -->
---
<!-- .slide: data-transition="fade" -->
### 一維陣列
----
<!-- .slide: data-transition="fade" -->
<h3 class="text-left">
一維陣列的宣告方式
</h3>
```cpp
int arr[105]; // 宣告int陣列 大小為105
```
**這指令告訴電腦你需要105個空間儲存int**
<!-- .element: class="fragment" data-fragment-index="1" -->
**如此一來他就會分配105個連續空間給你**
<!-- .element: class="fragment" data-fragment-index="2" -->
----
<!-- .slide: data-transition="fade" -->
**想當然爾 其他資料型態也可以宣告陣列**
```cpp
int arr[10];
char str[105];
float f1[10000];
double handsome[55];
```
----
<!-- .slide: data-transition="fade" -->
**陣列取用是使用編號來存取**
**假設我今天宣告了一個大小$100$的陣列**
**那我的陣列編號就會是$0$到$99$**
<!-- .element: class="fragment" data-fragment-index="1" -->
**假設我今天宣告了一個大小$n$的陣列**
**那我的陣列編號就會是$0$到$n - 1$**
<!-- .element: class="fragment" data-fragment-index="2" -->
----
<!-- .slide: data-transition="fade" -->
**陣列可以想像成格子**

**編號從$0$開始數算是慣例(我也不知道為什麼)**
<!-- .element: class="fragment" data-fragment-index="1" -->
----
<!-- .slide: data-transition="fade" -->
**裡面可以儲存數字**

----
<!-- .slide: data-transition="fade" -->
<h3 class="text-left">
一維陣列存取
</h3>
```cpp
int arr[8]; // 宣告大小 8 的int陣列
arr[0] = 10; // arr位置 0 存入 10
arr[5] = 20; // arr位置 0 存入 20
printf("%d %d", arr[0], arr[5]); // 輸出 "10 20"
```

----
<!-- .slide: data-transition="fade" -->
**編號一般稱為index或是idx**
**注意不可以去存取超出範圍的idx**

**這樣電腦會報錯**
**因為電腦看不懂這是哪裡**
<!-- .element: class="fragment" data-fragment-index="1" -->
---
<!-- .slide: data-transition="fade" -->
### 奇奇怪怪的一維陣列操作
----
<!-- .slide: data-transition="fade" -->
**操作陣列 我們通常會使用迴圈**
```cpp
int arr[10]; // 宣告大小 10 的陣列
for(int i = 0; i < 10; i++){ // i 從 0 到 10
arr[i] = i + 1; // 編號 idx=i 存入 i+1
}
for(int i = 0; i < 10; i++){
printf("%d ", arr[i]); // 輸出陣列編號 i 的數值
}
```
----
<!-- .slide: data-transition="fade" -->
**輸入十個數字**
```cpp
int arr[10]; // 宣告大小 10 的陣列
for(int i = 0; i < 10; i++){ // i 從 0 到 10
scanf("%d", &arr[i]); // 輸入陣列編號 i 的數值
}
for(int i = 0; i < 10; i++){
printf("%d ", arr[i]); // 輸出陣列編號 i 的數值
}
```
----
<!-- .slide: data-transition="fade" -->
**宣告時就塞數字給陣列**
```cpp
int arr[8] = {0, 8, 4, 8, 7, 8, 7, 8};
```

----
<!-- .slide: data-transition="fade" -->
**取陣列中的最小值**
```cpp
int arr[8] = {7, 9, -1, 3, 4, 15, 7, 2};
int mn = 105; // mn 一定要是一個比陣列內的數字還要大的值
for(int i = 0; i < 8; i++){
if(mn > arr[i]){
mn = arr[i];
}
}
printf("%d", &mn);
```
----
<!-- .slide: data-transition="fade" -->
**反著輸出陣列**
```cpp
int arr[8] = {7, 9, -1, 3, 4, 15, 7, 2}, n = 8;
for(int i = n - 1; i >= 0; i--){ // 從 n-1 到 0,每次 i 減 1
printf("%d ", arr[i]);
}
```
**或是**
```cpp
int arr[8] = {7, 9, -1, 3, 4, 15, 7, 2}, n = 8;
for(int i = 0; i < n; i++){
printf("%d ", arr[n - i - 1]); // 很trivial的減法操作
}
```
----
<!-- .slide: data-transition="fade" -->
**輸出陣列五次**
```cpp
int arr[8] = {7, 9, -1, 3, 4, 15, 7, 2}, n = 8, m = 5;
for(int i = 0; i < m; i++){ // 重複 m 次
for(int j = 0; j < n; j++){ // 輸出 arr[i], i = 0 ~ n-1
printf("%d ", arr[j]);
}
printf("\n"); // 換行
}
```
**或是**
```cpp
int arr[8] = {7, 9, -1, 3, 4, 15, 7, 2}, n = 8, m = 5;
for(int i = 0; i < m * n; i++){ // 重複 m * n 次
printf("%d%c", arr[i % n], " \n"[(i + 1) % n == 0]);
} // 純炫技,看不懂請見諒,有興趣研究者歡迎詢問
```
----
**宣告陣列時歸零**
```cpp
int arr[10000] = {0};
```
----
**輸入n個數字並找出[眾數](https://zh.wikipedia.org/zh-tw/%E4%BC%97%E6%95%B0_(%E6%95%B0%E5%AD%A6))**
```cpp
int arr[105] = {0}, n, tmp;
scanf("%d", &n); // 輸入n
for(int i = 0; i < n; i++){ // 輸入 n 個數字
scanf("%d", &tmp);
arr[tmp]++; // 編號 tmp 的位置 +1
}
int mx = -1, ans = 0; // 找最大值 並用 ans 紀錄答案
for(int i = 0; i < 105; i++){
if(mx < arr[i]){
mx = arr[i];
ans = i;
}
}
printf("眾數: %d, 出現%d次", ans, mx);
```
**注意這樣寫只能紀錄 0~104 的數字**
<!-- .element: class="fragment" data-fragment-index="1" -->
----
<!-- .slide: data-transition="fade" -->
**一維陣列操作還有很多很多...**
**如果以上範例沒有你想要的**
**歡迎自己研發新的寫法喔**
---
<!-- .slide: data-transition="fade" -->
### 二維陣列
----
<!-- .slide: data-transition="fade" -->
**二維陣列就是他的idx有兩個**
**一般來說就是用兩個[]表示**
----
<!-- .slide: data-transition="fade" -->
**像arr[i][j] 就是arr陣列第i, j個位置**

**可以畫成網格狀來表示位置**
----
<!-- .slide: data-transition="fade" -->
**有些網路上的文章會寫
i 稱為行(column)
j 稱為列(row)**
**跟我們在數學上的矩陣叫法一樣**
<!-- .element: class="fragment" data-fragment-index="1" -->
----
<!-- .slide: data-transition="fade" -->
<h3 class="text-left">
二維陣列宣告
</h3>
```cpp
int arr[105][15]; // 宣告一個 105 * 15 的陣列
```
----
<!-- .slide: data-transition="fade" -->
<h3 class="text-left">
二維陣列存取
</h3>
```cpp
int arr[8][6]; // 宣告一個 8 * 6 的陣列
arr[5][4] = 87; // i=5, j=4 的位置 存入 87
arr[2][0] = 4; // i=2, j=0 的位置 存入 4
printf("%d", arr[5][[4]]); // 輸出 87
```
<img src="https://hackmd.io/_uploads/rJyS0aYc0.png" style="width: 600px">
---
<!-- .slide: data-transition="fade" -->
### 奇奇怪怪的二維陣列操作
----
<!-- .slide: data-transition="fade" -->
**輸入輸出二維陣列**
```cpp
int arr[8][6]; // 宣告一個 8 * 6 的陣列
for(int i = 0; i < 8; i++){ // column
for(int j = 0; j < 6; j++){ // row
scanf("%d", &arr[i][j]); // 輸入 arr[i][j]
}
}
for(int i = 0; i < 8; i++){ // column
for(int j = 0; j < 6; j++){ // row
printf("%d ", arr[i][j]); // 輸出 arr[i][j]
}
printf("\n"); // 換行
}
```
----
**宣告時就把數字塞入二維陣列**
```cpp
int arr[3][6] = {
{1, 2, 3, 4, 5, 6},
{2, 4, 6, 8, 10, 12},
{3, 6, 9, 12, 15, 18}
};
```
----
<!-- .slide: data-transition="fade" -->
**更多奇奇怪怪的用法
可以在動態規劃裡面看到**
---
<!-- .slide: data-transition="fade" -->
### 例題練習
----
<!-- .slide: data-transition="fade" -->
[Zerojudge d786. 三、平均值](https://zerojudge.tw/ShowProblem?problemid=d786)
[CSES Missing Number](https://cses.fi/problemset/task/1083)
[Zerojudge b374. [福州19中]众数](https://zerojudge.tw/ShowProblem?problemid=b374)
[Zerojudge g595. 1. 修補圍籬](https://zerojudge.tw/ShowProblem?problemid=g595)
[Zerojudge g498. 兔子跳躍 (Rabbit)](https://zerojudge.tw/ShowProblem?problemid=g498)
[Zerojudge c638. 天干地支](https://zerojudge.tw/ShowProblem?problemid=c638)
[Zerojudge m398. 超市排隊 (Supermarket)](https://zerojudge.tw/ShowProblem?problemid=m398)
[Zerojudge c561. Bert 愛搗蛋](https://zerojudge.tw/ShowProblem?problemid=c561)
----
[CSES Number Spiral](https://cses.fi/problemset/task/1071)
[Zerojudge e798. p5. 卷積神經網路](https://zerojudge.tw/ShowProblem?problemid=e798)
[Zerojudge a015. 矩陣的翻轉](https://zerojudge.tw/ShowProblem?problemid=a015)
[Zerojudge b266. 矩陣翻轉](https://zerojudge.tw/ShowProblem?problemid=b266)
[Zerojudge e339. 前綴和練習](https://zerojudge.tw/ShowProblem?problemid=e339)
[Zerojudge c292. APCS2017-0304-3數字龍捲風](https://zerojudge.tw/ShowProblem?problemid=c292)
**要用億點點數學跟前面學過的內容喔**
<!-- .element: class="fragment" data-fragment-index="1" -->
----
**PS: 這章節的練習題有點刁難初學者
\><**
---
<!-- .slide: data-transition="fade" -->
### 以上就是本章節的內容
{"description":"認識陣列","title":"C程式設計導論-陣列","contributors":"[{\"id\":\"4f67a8cd-06ae-45dc-a8e3-62c6a41e5a37\",\"add\":8533,\"del\":597}]"}