实际需求
编写的五子棋程序中,有存盘退出和续上盘的功能

如果按照原始的方式来存储二维数组,因为该二维数组很多值是默认值0,因此记录了很多没有意义的数据。
基本介绍
当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来存储该数组。
稀疏数组的处理方法是:
- 记录数组一共有几行几列,有多少个不同的值
- 把具有不同值的行列及值记录在一个小规模的数组中,从而缩小程序的规模
应用实例
使用稀疏数组来保留类似前面的二维数组(棋盘、地图等),把稀疏数组存盘,并且可以重新恢复原来的二维数组。
实现思路:

代码实现
package main
import (
"bufio"
"fmt"
"io"
"os"
"strconv"
"strings"
)
type ValNode struct {
Row int
Col int
Val int
}
func main() {
// 先创建一个原始数组 1 表示黑子,2表示蓝子
var chessMap [11][11]int
chessMap[1][2] = 1
chessMap[2][3] = 2
// 输出查看原始的数组
for _, v := range chessMap {
for _, v2 := range v {
fmt.Printf("%d\t", v2)
}
fmt.Println()
}
// 转成稀疏数组
// 遍历chessMap ,如果发现有一个元素的值不为0,创建一个node结构体,将其放入到对应的切片即可
var sparseArr []ValNode
// 标准的一个稀疏数组应该还有一个记录元素的二维数组的规模(行、列、默认值)
valNode := ValNode{
Row: 11,
Col: 11,
Val: 0,
}
sparseArr = append(sparseArr, valNode)
for i, v := range chessMap {
for j, v2 := range v {
if v2 != 0 {
// 创建一个valNode 值节点
valNode2 := ValNode{
Row: i,
Col: j,
Val: v2,
}
sparseArr = append(sparseArr, valNode2)
}
}
}
// 输出稀疏数组
fmt.Println("当前的稀疏数组是::::::")
for i, valNode := range sparseArr {
fmt.Printf("%d: %d %d %d\n", i, valNode.Row, valNode.Col, valNode.Val)
}
// 将稀疏数组存盘 /mnt/chessmap.data
filePath := "/tmp/chessmap.data"
file, _ := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE, 0666)
defer file.Close()
writer := bufio.NewWriter(file)
for _, val := range sparseArr {
writeString := fmt.Sprintf("%d %d %d\n", val.Row, val.Col, val.Val)
writer.WriteString(writeString)
}
writer.Flush()
// 打开文件 chessmap.data 恢复原始数组
var fileConentArr []ValNode
fileOpen, _ := os.Open(filePath)
defer file.Close()
reader := bufio.NewReader(fileOpen)
for {
str, err := reader.ReadString('\n')
if err == io.EOF {
break
}
strArr := strings.Split(str, " ")
if len(strArr) == 3 {
strArr[2] = strings.Replace(strArr[2], "\n", "", -1) // 将最后的换行符去掉
row, _ := strconv.Atoi(strArr[0])
col, _ := strconv.Atoi(strArr[1])
val, _ := strconv.Atoi(strArr[2])
valNode := ValNode{
Row: row,
Col: col,
Val: val,
}
fileConentArr = append(fileConentArr, valNode)
}
}
// 使用稀疏数组恢复数据
var chessMap2 [11][11]int
for i, valNode := range fileConentArr {
if i != 0 { // 跳过第一行记录纸,因为第一行是记录的数组大小
chessMap2[valNode.Row][valNode.Col] = valNode.Val
}
}
// 查看恢复是否正确
fmt.Println("恢复后的数据。。。。。")
for _, v := range chessMap2 {
for _, v2 := range v {
fmt.Printf("%d\t", v2)
}
fmt.Println()
}
}
输出结果:
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 当前的稀疏数组是:::::: 0: 11 11 0 1: 1 2 1 2: 2 3 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