iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 2
5
Software Development

擁抱「資料結構」的「演算法」系列 第 2

擁抱「資料結構」的「演算法」(02) - 陣列 Array

前言

今天要來介紹第一種資料結構:陣列,算是最淺顯易懂的一種線性串列,從字面上的意思來看,大概可以猜出,資料會排成一列一列的,一起來觀察一下生活中的例子吧


生活常識

在生活中有沒有什麼東西是排成一列一列的呢?像是排隊買口罩XD,還是像書一本一本的排列在書櫃裡,建築一棟房子或是搭乘捷運、火車、高鐵,好像都觀察到排列的情形

而我自己是想到了一個有趣的經驗,大家有沒有去便利商店買過飲料,從擺滿各式各樣飲料的冰箱裡,拿出一罐飲料時,請你回想一下那個畫面,有沒有發生什麼有趣的現象,除了手上會多一罐飲料之外,冰箱裡面會發生什麼事情呢?如果覺得滿頭問號的話,可以參考一下我拍的影片哦~從影片中可以觀察到,當第一罐飲料被拿走時,其他飲料會自動往前遞補,這樣的冰箱設計是不是很神奇!

在生活中充滿了許多排列的例子,但在電腦世界裡,資料的排列又是如何進行的?有沒有什麼令人驚豔的特別之處呢?讓我們一同來瞭解看看吧!


專業知識 - 陣列 Array

雖然從字面上的意思,感覺是資料排成一列一列的,但其實 陣列 還有其他的特性與限制
1. 可以用來儲存一群相同類型的資料
2. 會使用一段連續的記憶體空間來存放
3. 必須明確定義要存放多少數量的資料
4. 可透過索引快速存取資料
5. 不方便做資料的追加與刪除

可能看文字描述會覺得文謅謅的,所以一樣舉生活例子,一個禮拜有 7 天,小美想要在每一天都吃不同的保健食品,他考慮買個藥盒,裡面裝著每一天分配好的保健品,方便提醒自己

https://ithelp.ithome.com.tw/upload/images/20200916/201298413NRaLIwk29.jpg
圖片來源 : momo

一個盒子總共有 7 個格子,分別代表週一到週六週日,小美做了以下的安排:
https://ithelp.ithome.com.tw/upload/images/20200918/20129841o5w0sVSzLL.png

把上述例子套用在資料結構的陣列中,會變成下面這樣:

1. 可以用來儲存一群相同類型的資料

盒子可以拿來裝保健食品,保健食品就是一種類型(不會拿去裝安眠藥、感冒藥,誤食可能會影響上班狀態)

2. 會使用一段連續的記憶體空間來存放

有一排連續的格子可以提供空間來存放保健食品

3. 必須明確定義要存放多少數量的資料

總共有7格,分別可以7種保健食品 (如果數量隨時都會有增有減,無法明確定義的話,那會推薦改用其他種資料結構,後續會介紹)

4. 可透過索引快速存取資料

如果今天是週一,就可以直接找到寫著週一的格子,直接把保健品全部吃掉就可以了,不用像傳統作法,可能會帶7大罐保建食品去公司的抽屜放,抽屜還亂七八糟,吃的時候還要花心思找XD

5. 不方便做記憶體空間的追加與刪除

如果吃了一段時間,想要調整保健品的順序,例如週一要改吃維他命C,週五改吃B群,那會發現,整個盒子的內容物可能需要大搬風,或者要將保健食品拿出來並做一些調整,十分麻煩,如下表,全部的保健品都要全部拿出來重放

https://ithelp.ithome.com.tw/upload/images/20200918/20129841zkXahtL488.png

當盒子太小
當今天想在多吃一些新的保健食品,但盒子只有 7 個格子,也會有大麻煩,由於盒子在開發製造的時候,就一體成形,可能只能買新的盒子

當盒子太大
如果今天想要換成 6 格,就會比較麻煩,那要看能不能把多的格子拿鋸子鋸掉XD,不然多那一格放著不用也是顯得浪費或是占空間,亦或是在買一個新的盒子內含6格,不論如何,就是不方便!

索引 vs 值

那回到電腦的記憶體中,陣列又是如何存放這些資料的呢?我們在宣告產生一個陣列變數時,就會產生一段連續的空間,並透過索引去存取該空間的值,索引初始位置從 0 開始,就如同藥盒在生產時,就明確的製造出7格連續的格子可以存放保健品

索引初始位置從 0 開始
索引初始位置從 0 開始
索引初始位置從 0 開始

https://ithelp.ithome.com.tw/upload/images/20200918/20129841Kdc9ZLnbES.png

我們來看看以 C# 的方式,會如何新增或存取陣列,首先,先宣告一個名稱為 box,型態是陣列的變數,陣列長度為 7 ,可以用來存放文字,接著將每一種保健食品分別寫入相對應的索引

變數名稱[索引位置] = 要存放的值
變數名稱[索引位置] = 要存放的值
變數名稱[索引位置] = 要存放的值

var box = new string[7]; //不多也不少,就是只有7個空間
box[0] = "維他命D"; //變數名稱[索引位置] = 要存放的值
box[1] = "葉黃素";
box[2] = "蔓越莓錠";
box[3] = "B群";
box[4] = "綜合維他命";
box[5] = "益生菌";
box[6] = "維他命C";

https://ithelp.ithome.com.tw/upload/images/20200918/201298412X3ZnbTtQ7.png

如果要透過程式,了解小美週三吃什麼保健食品,要怎麼做呢,

變數名稱[索引位置]
變數名稱[索引位置]
變數名稱[索引位置]

使用 box[2] 來存取,就會得到小美週三固定會吃蔓越莓錠

當陣列太小
當陣列不夠用時,那就要新宣告變數來存放資料,因為陣列必須使用連續的記憶體,當 box 的陣列長度只有 7 的時候,你無法確定記憶體中第 8 格有沒有被其他人使用了,所以只好透過宣告一個新變數的方式

var newBox = new string[8]; 

這時候電腦找一段連續的記憶體空間,然後你要自己將 box 內的值逐一搬到 newbox 裡面去,是不是很麻煩呢XD

當陣列太大
當陣列有多餘的空間時,一樣要新宣告變數,再將 box 內的值逐一搬到 newbox 裡面去

var newBox = new string[6]; 

透過上述情況,可以得知陣列的長度再宣告的時候就會被固定,後續的增減都會麻煩許多,所以請大家在使用陣列時,一定審慎評估


今日小結

陣列在生活中的例子就很像是一體成型的汽車或冰箱,當可收納的空間不足的時候,就需要汰舊換新,但這種情況很少年,可能好幾年或好幾十年才會遇到一次。在電腦世界中,陣列適合存放固定數量的資料,且可以透過索引快速存取,如果數量會常常遇到增減,或是資料常常會有大搬風的需求,那麼就要考慮使用其他類型的資料結構。常使用到陣列的例子,像是統計一篇英文文章中,a-z出現的次數,因為我們很確定英文字母最多就是 26 個,不會有 27 或 28 個,所以我們就可以宣告一個長度為 26 的陣列去做數量的統計

var letters = new int[26];

如果想要知道字母 A 出現幾次就可以呼叫 letters[0], 想要知道字母 Z 出現幾次就可以呼叫 letters[25]


每日解謎

https://ithelp.ithome.com.tw/upload/images/20200916/20129841vMXEnltvup.jpg
圖片來源:https://unsplash.com/photos/r2PBy6dWJE0

因為報復性消費,本旅社最近入住率100%,目前總共有10間房間,通通客滿

房號 1 2 3 4 5 6 7 8 9 10
姓名 A 小姐 c 先生 e 先生 r 小姐 Y 先生 F 小姐 R 先生 z 先生 G 小姐 a 先生

就在今天下午,第 2、3、6、8、9 間的房客紛紛辦理退房,而就在此時此刻,有一些房客提出想換房間的要求,因為他們都是超級VVIP,一定要辦理,但他們留下了神祕的訊息,似乎在考驗你什麼,你能解讀嗎?

house[1] = house[3];
house[3] = "";

house[2] = house[6];
house[6] = "";

house[3] = house[9];
house[9] = "";

在終於忙完所有事項之後,你有沒有發現什麼隱藏的訊息呢?歡迎留言哦XD


上一篇
擁抱「資料結構」的「演算法」(01) - 何謂資料結構
下一篇
擁抱「資料結構」的「演算法」(03) - 多維陣列 Multidimensional Arrays
系列文
擁抱「資料結構」的「演算法」30

1 則留言

0
ice bear
iT邦新手 4 級 ‧ 2021-01-27 10:05:34

神秘訊息是Array嗎XD

小菜 iT邦新手 5 級 ‧ 2021-02-21 07:50:28 檢舉

耶~~~ 答對了XD
詳細解答可以參考下一篇的最下方哦~
https://ithelp.ithome.com.tw/articles/10238366

我要留言

立即登入留言