擁抱「資料結構」的「演算法」(03) - 多維陣列 Multidimensional Arrays

 

前言(其實就是拉D賽時間)

看了昨天的陣列介紹之後,是不是覺得很簡單呢?對於資訊相關領域的人而言,陣列是很好理解的一種資料結構,但對於其他非資訊背景的人而言,似乎在陣列索引要從 0 開始的這個地方,會稍微卡住,對於如何透過程式存取資料更卡,會需要花一點時間理解,為什麼我會知道呢?因為還特地找了朋友來盲測一下XD,看他能不能成功答對謎題,大概就知道他是真的懂,還是似懂非懂了!很開心他最後有成功解題,突然覺得這系列應該是寫給非資訊相關領域的人看的XD,大家如果覺得我寫得太簡單,還請大家多多包涵吶!


生活常識

多維,就是多個維度(被揍),根據維度多寡,又可以分 1 維、2 維、3 維與 N 維,而什麼是維度呢?

一維

一維是指一條線,可以在這條線上去延展,比如拔河運動,裁判只注意繩子到底是往右偏還是往左偏



二維

二維是指一個平面,像棋盤是由直線橫線所組成的格子



或是像經度緯度,可以用來記錄颱風的移動路徑



三維

三維是指一個立方體,基於二維平面上,再加上高度的話,就會有寬與高`,三個維度,比如說:3 X 3 X 3 的魔術方塊


或是像三維座標會包含:X軸、Y軸與Z軸,或者像經度緯度再加上一個海拔高度,也是三維空間

N維

有三維當然就會有四維、五維或是更高的維度,但其實四維以上就可以稱為 N 維了,如果參考愛因斯坦的相關理論,可能就是三維空間再加上了時間的概念,也許是昨天中午我在辦公室跟大家吃飯,但今天中午在辦公室趕案子沒有吃飯,依樣是待在辦公室,但不同的時間點,可能會有不同的情境發生,而在現實中活中,是如何紀錄每一個空間與時間下發生什麼事情,就無從考察了,也許是以某種特別的形式紀錄在這個宇宙中吧~


專業知識 - 多維陣列 Multidimensional Arrays

多維陣列,一樣進行說文解字XD,從字面上的意思,感覺就是有多個陣列(被揍),根據陣列的維度多寡,又可以分 1 維陣列、2 維陣列、3 維陣列與 N 維陣列

一維陣列 One-Dimensional Array

昨天介紹的內容就是一維陣列,陣列可以儲存多個元素,我們可以宣告一個 box 變數,可存放 7 個字串型態(string)的陣列,並使用{}大括號來初始化數值,用來記錄小美在一週內每一天所吃的保健食品



  var box = new string[3] = {"維他命D","葉黃素","蔓越莓錠","B群","綜合維他命","益生菌","維他命C"};

二維陣列 Two-Dimensional Array

如果小美吃了一段時間之後,發現每天只吃一種保健食品,好像營養不夠平均,於是他想規劃一週每一天早上、中午與下午都要吃不一樣的保健食品,昨天的盒子肯定無法滿足他新的需求,這下想必小美要購入新的盒子

那小美要添購什麼樣的盒子,才能符合他的需求?因為小美須要根據今天是星期幾以及今天是什麼時段,才能決定要做什麼樣的安排,所以表示小美必須考慮兩個維度的事情星期時段

  • 吃保健食品有3 個時段:上午、中午與下午
  • 一星期有7 天
  • 3 個時段 * 7 天 = 21 格
    所以我們可以得知,小美必須購買21格的盒子才符合他的需求



圖片來源:momo

初始化陣列,先盤點需要多少空間:

  • 需要 3 列 Row (每天有 3 個時段)
  • 需要 7 行 Column (一週 7 天)
  • 會得到3 * 7 的二維陣列,得到 21 個記憶體空間


透過以下程式宣告變數,並初始化數值

var box = new string[3,7] { //會得到 3 * 7 共 21 個記憶體空間
   //↓週一~週日
 {"維他命D","葉黃素","蔓越莓錠","B群","綜合維他命","益生菌","維他命C"}, //上午
 {"葉黃素","蔓越莓錠","B群","綜合維他命","益生菌","維他命C","維他命D"}, //中午
 {"蔓越莓錠","B群","綜合維他命","益生菌","維他命C","維他命D","葉黃素"}}; //下午

存取變數:變數名稱[列索引號, 行索引號]
存取變數:變數名稱[列索引號, 行索引號]
存取變數:變數名稱[列索引號, 行索引號]

如果想了解小美禮拜六下午吃什麼?就可以存取box[時段索引號, 星期索引號],即為 box[2,5],就可以得知小美吃的是維他命D,要記得陣列的索引都是從 0 開始哦!如果不清楚,可以參考上圖表格的橘色框框有標上索引編號

其實二維陣列使用的方式,跟建立 Word 表格的有點相似,在建立的時候就要清楚地給予 Column 與 Row 的數值才能建立表格



而在實務上,也可以使用二維陣列來計算矩陣相加與相乘,或是可以統計玩家手上的撲克牌,像是可以宣告4 種花色 * 13 種點數 = 共 52 個空間來記憶

var cards = new int[4,13]


例如玩家希望電腦推薦出牌策略,那透過程式碼cards[花色索引號, 點數索引號],如果要檢查玩家有沒有拿到點數 2 ,即檢查 cards[0,1]、cards[1,1]、cards[2,1]、cards[3,1],發現這四格的值都是 1,表示這位玩家拿到 4 張點數 2,那們這位玩家勝出機率就很高了,電腦就可以推薦一些出牌策略給這個玩家

三維陣列 Three-Dimensional Array

如果今天小美,他覺得每週都要分配一次保健品很麻煩,他想要將一個月份,共 4 週的藥品,全部都放好,想必... 他又要買盒子了,因為目前盒子只能裝一週的分量,這次小美可能要換買箱子才可以了XD

圖片來源:momo

宣告陣列,先盤點需要多少空間:

  • 一個月有 4 週
  • 每天有 3 個時段
  • 一週 7 天
  • 會得到 4 * 3 * 7 的三維陣列
var box = new string[4,3,7] {
{//第一週,索引0
 {"維他命D","葉黃素","蔓越莓錠","B群","綜合維他命","益生菌","維他命C"}, //早上
 {"葉黃素","蔓越莓錠","B群","綜合維他命","益生菌","維他命C","維他命D"}, //中午
 {"蔓越莓錠","B群","綜合維他命","益生菌","維他命C","維他命D","葉黃素"}  //下午
},	
{//第二週,索引1
 {"維他命D","益生菌","蔓越莓錠","B群","綜合維他命","葉黃素","維他命C"}, //早上
 {"維他命C","蔓越莓錠","B群","綜合維他命","益生菌","葉黃素","維他命D"}, //中午
 {"維他命D","綜合維他命","B群","益生菌","維他命C","蔓越莓錠","葉黃素"}  //下午
},	
{//第三週,索引2
 {"維他命D","葉黃素","蔓越莓錠","B群","綜合維他命","益生菌","維他命C"}, //早上
 {"葉黃素","蔓越莓錠","B群","綜合維他命","益生菌","維他命C","維他命D"}, //中午
 {"蔓越莓錠","B群","綜合維他命","益生菌","維他命C","維他命D","葉黃素"}  //下午
},	
{//第四週,索引3
 //週一索引0, 週2索引1,以此類推,週日索引6
 {"維他命D","葉黃素","蔓越莓錠","B群","綜合維他命","益生菌","維他命C"}, //早上 0
 {"葉黃素","益生菌","B群","綜合維他命","蔓越莓錠","維他命C","維他命D"}, //中午 1
 {"蔓越莓錠","B群","葉黃素","益生菌","維他命C","維他命D","綜合維他命"}  //下午 2
}};

如果想知道小美吃什麼,就可以使用程式碼box[週次索引號, 時段索引號, 星期索引號]去查詢,比如第 4 週,禮拜天,晚上吃什麼,可呼叫box[3,2,6],即可得知吃的是綜合維他命

實際應用的話,可以用於記錄學生的月考分數,盤點維度:

  1. 多位學生
  2. 多個考試科目
  3. 多個月份

N維陣列 N-Dimensional Array

一樣的例子在堆疊上去
記錄學生高一到高三的月考分數,盤點維度:

  1. 多位學生
  2. 多個考試科目
  3. 多個月份
  4. 多個年度
    這樣就是 4 維陣列囉

今日小結

常見的陣列為一維與二維,三維或多維真的會開始腦袋有點打結,會有類似一對多,然後再往下一對多去做資料的存取,會比較複雜一些,建議大家在使用多維度陣列的時候,一定要清楚自己的維度設計,才能正確儲存與存取到資料


今日謎題

你發現了一張藏寶地圖,上面留有一些像是座標的程式碼訊息,你能找出關鍵提示嗎?

Maps[2,2]
Maps[0,1]
Maps[3,0]
Maps[1,3]
Maps[4,0]
Maps[5,0]
Maps[5,3]
Maps[4,1]
Maps[7,1]



昨日謎題

需清楚掌握前一篇的重點

  1. 陣列索引初始位置從 0 開始
  2. 取值:變數名稱[索引位置]
  3. 更新數值:變數名稱[索引位置] = 要存放的值

解題步驟如下:
請注意房號是給管理人員或是房客辨認使用的,跟陣列的索引,兩者之間是沒有關係的哦,陣列索引永遠都是從 0 開始,而房號就見仁見智了,可以叫 A 房、 B 房、 C 房或是天鵝房,只要管理人員或房客可以辨識就可以哦!



你猜到神秘客要給你的訊息了嗎?答案就是 ArRaY,陣列的英文 Array

圖片來源:
https://unsplash.com/photos/SlntP-SLi0Q
https://unsplash.com/photos/4eTnTQle0Ks

留言

這個網誌中的熱門文章

CPE 一顆星選集題目說明與解答 - Java 筆記與心得分享

Visual Studio 自動排版格式化程式碼

1. Vito's family (CPE10406, UVA10041) - CPE一顆星解答與說明