什麼是稀疏數組
當一個數組中的數據大部分都是默認數據,此時數組數據需要存盤的情況下,大量默認數據也會佔用存儲空間。稀疏數組正是用於解決此類問題,稀疏數組只存在數據在原始數組中的位置及值,在存盤時只報存稀疏數組中的數據即可;當讀取文件時根據稀疏數組來還原 原始數組。
作用:減少存儲空間,起到類似數據壓縮的作用。
下面就來使用一個簡單案例介紹一下稀疏數組的使用
問題引出:
下面介紹一個遊戲-五子棋,大家都知道棋盤是一個縱橫交錯的線劃分而成的,其實轉變一下就變成了編程中的二維數組,每個點都是數組中的一個座標,下就來代入一下
* 二維數組模擬五子棋棋盤
* 1:白子;2:黑子
* 棋盤效果模擬圖如下:
* 0 0 0 0 0 0 0 0 0 0 0
* 0 0 1 0 0 0 0 0 0 0 0
* 0 0 0 2 0 0 0 0 0 0 0
* 0 0 0 0 0 0 0 0 0 0 0
* 0 0 0 0 0 0 0 0 0 0 0
* 0 0 0 0 0 0 0 0 0 0 0
* 0 0 0 0 0 0 0 0 0 0 0
* 0 0 0 0 0 0 0 0 0 0 0
* 0 0 0 0 0 0 0 0 0 0 0
* 0 0 0 0 0 0 0 0 0 0 0
* 0 0 0 0 0 0 0 0 0 0 0
//1.定義行列的長度
val rowSize = 11
val colSize = 11
//2.定義二維數組
val array = Array.ofDim[Int](rowSize, colSize)
array(1)(2) = 1
array(2)(3) = 2
問題:如下棋盤是一個二維數組保存數據,假設此時棋手需要暫存遊戲下次繼續玩,而此時棋盤上面棋子並不多,如果對整個數組中數據進行存盤則默認無子也會佔用空間。
解決:在棋子不多的情況下,使用稀疏數組來記錄每個棋子的橫縱座標以及棋子類型即可,在實際存盤時只需要保存這些已經落下的棋子即可
//記錄一個棋子數據,行-列-值
class Node(val row: Int, val col: Int, val value: Int) {
override def toString: String = row + "\t" + col + "\t" + value
}
下面使用完整代碼演示:
object SparseArr {
def main(args: Array[String]): Unit = {
//1.定義行列的長度
val rowSize = 11
val colSize = 11
//2.定義二維數組
val array = Array.ofDim[Int](rowSize, colSize)
array(1)(2) = 1
array(2)(3) = 2
var count: Int = 2 //記錄棋子個數
//3.查看棋盤
showQipan(array)
//4. 稀疏數組解決存儲過大問題
//問題:由棋盤顯示可以看出默認無子爲0,則在棋子較少時保存棋盤情況入磁盤時0也會佔用存儲空間,怎麼來進行存儲空間優化?
//解決:在棋子較少時,使用稀疏數組來保存已經落下的棋子位置,因爲無子默認爲0則不用保存,這樣會減少實際存儲空間
//其實在定義這個數組時可以根據已經落下多少顆棋子來定義
val sparseArr = new ArrayBuffer[Node](count + 1) //多出一個記錄棋盤大小
val node = new Node(rowSize, colSize, 0) //棋盤大小
sparseArr.append(node)
//保存棋子
for (i <- 0 until array.length) {
for (j <- 0 until array(i).length) {
//棋子不爲0保存
if (array(i)(j) != 0) {
sparseArr.append(new Node(i, j, array(i)(j)))
}
}
}
//5. 文件io操作
val datas = showSparseArr(sparseArr)
//顯示稀疏數組結果
//落地爲磁盤文件
val fileName = "d:/1.txt"
FileUtil.write(fileName)(datas)
println("------------文件讀取----------")
//文件數據加載
val nodes = FileUtil.read(fileName)
nodes.foreach(println(_))
println("------------稀疏數組還原棋盤----------")
//6.根據文件讀取數據,還原完整棋盤
val ar2 = Array.ofDim[Int](rowSize, colSize)
for (i <- 1 until nodes.length) {
val node = nodes(i)
ar2(node.row)(node.col) = node.value
}
for (items <- ar2) {
for (i <- items) {
print(i + "\t")
}
println()
}
}
//棋盤顯示函數
def showQipan(array: Array[Array[Int]]): Unit = {
for (items <- array) {
for (i <- items) {
print(i + "\t")
}
println()
}
}
def showSparseArr(arr: ArrayBuffer[Node]) = {
val strs = new ArrayBuffer[String]()
for (node <- arr) {
// println(node)
strs.append(node.toString)
}
strs.toArray
}
}
//記錄一個棋子數據,行-列-值
class Node(val row: Int, val col: Int, val value: Int) {
override def toString: String = row + "\t" + col + "\t" + value
}
終結:當數組中數據大量是默認數據時需要存盤,則可以使用稀疏數據完成數據壓縮作用