101、稀疏數組介紹

什麼是稀疏數組

當一個數組中的數據大部分都是默認數據,此時數組數據需要存盤的情況下,大量默認數據也會佔用存儲空間。稀疏數組正是用於解決此類問題,稀疏數組只存在數據在原始數組中的位置及值,在存盤時只報存稀疏數組中的數據即可;當讀取文件時根據稀疏數組來還原 原始數組。

作用:減少存儲空間,起到類似數據壓縮的作用。

下面就來使用一個簡單案例介紹一下稀疏數組的使用

問題引出:

下面介紹一個遊戲-五子棋,大家都知道棋盤是一個縱橫交錯的線劃分而成的,其實轉變一下就變成了編程中的二維數組,每個點都是數組中的一個座標,下就來代入一下


  * 二維數組模擬五子棋棋盤
  * 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
}

終結:當數組中數據大量是默認數據時需要存盤,則可以使用稀疏數據完成數據壓縮作用

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章