基本介绍
当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。
稀疏数组的处理方法是:
- 记录数组一共有几行几列,有多少个不同的值
- 把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模
案例需求
代码
这里为了数据转化方便,我存放数据采用的是 map切片,
// sparseArr 落盘数据
11 11 0
1 2 1
2 3 2
// sparseArrObj 序列化后落盘数据
[{"col":11,"row":11,"val":0},{"col":2,"row":1,"val":1},{"col":3,"row":2,"val":2}]
思考:
应不应该考虑写入文件的数据量大小?稀松数组
chessMap [[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]]
sparseArr [{11 11 0} {1 2 1} {2 3 2}]
sparseArrObj [map[col:11 row:11 val:0] map[col:2 row:1 val:1] map[col:3 row:2 val:2]]
// 稀疏数组 - 保留棋盘
package main
import (
"bufio"
"encoding/json"
"fmt"
"io"
"os"
)
type ValNode struct {
row int
col int
val int // int
}
func main() {
// 1. 原始数组, 二维数组
var chessMap [11][11]int
chessMap[1][2] = 1 // 1 - 黑子
chessMap[2][3] = 2 // 1 - 蓝子
chessMap[5][5] = 2 // 1 - 蓝子
// 2. 输出看看原始的数组
for _, v := range chessMap {
for _, v2 := range v {
fmt.Printf("%d \t", v2)
}
fmt.Println()
}
// 3. 转成新数组 - 稀疏数组
// 遍历数组,把值不为0的,创建一个 ValNode 结构体实例, 然后放入对应的切片
// 定义切片
var sparseArrObj []map[string]int
// 标准的稀疏数组,含有记录二维数组的规模
var obj map[string]int = make(map[string]int)
obj["row"] = 11
obj["col"] = 11
obj["val"] = 0
sparseArrObj = append(sparseArrObj, obj)
fmt.Println("sparseArrObj", sparseArrObj)
for row, v := range chessMap {
for col, v2 := range v {
if v2 != 0 {
var obj map[string]int = make(map[string]int)
obj["row"] = row
obj["col"] = col
obj["val"] = v2
sparseArrObj = append(sparseArrObj, obj)
}
}
}
// 4. 输出稀疏数组
fmt.Println("map切片:")
for i, _map := range sparseArrObj {
fmt.Printf("%d: %d\t%d\t%d\n", i, _map["row"], _map["col"], _map["val"])
}
// 存盘退出 续上盘
// 5. 存盘 : 稀松数组保存到文件 chessmap.data
fmt.Println("存盘数据, 'd:/chessmap.data'")
filepath := "d:/chessmap.data"
file, err := os.OpenFile(filepath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
if err != nil {
fmt.Println("打开文件失败")
return
}
defer func() {
err = file.Close()
if err != nil {
fmt.Println("关闭文件错误")
}
}()
// 写入数据, 带缓冲, writer.Flush()
writer := bufio.NewWriter(file)
// 5.1 序列化数据,存入文件,
data, err := json.Marshal(sparseArrObj)
if err != nil {
fmt.Println("序列化失败", err)
return
}
fmt.Println("sparseArrObj 序列化后: ", string(data))
writer.WriteString(string(data))
// 缓存落盘
writer.Flush()
// 6. 续上盘 :读取 chessmap.data 文件,遍历每一行, 恢复数组
_file, err := os.OpenFile(filepath, os.O_RDWR|os.O_APPEND, 0666)
if err != nil {
fmt.Println("打开文件失败")
return
}
// 6.1 读取内容
fmt.Println("文件读取输出")
var oldData string
reader := bufio.NewReader(_file)
for {
// 读到一个换行就结束
oldData, err = reader.ReadString('\n')
// 输出内容
fmt.Println("oldData=", oldData)
if err == io.EOF {
// 读到一行末尾
break
}
}
// 6.2 反序列化
var _sparseArrObj []map[string]int
err = json.Unmarshal([]byte(oldData), &_sparseArrObj)
if err != nil {
fmt.Println("反序列化失败", err)
return
}
fmt.Println("反序列化结果: ", _sparseArrObj)
// 7. 还原原始数组, 这里写死数组元素的个数, 应该使用切片,
var newChessMap [11][11]int
for i, _map := range _sparseArrObj {
if i != 0 {
newChessMap[_map["row"]][_map["col"]] = _map["val"]
}
}
// 7.1 输出原始数组
fmt.Println("======================")
for _, v := range newChessMap {
for _, v2 := range v {
fmt.Printf("%d \t", v2)
}
fmt.Println()
}
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 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
sparseArrObj [map[col:11 row:11 val:0]]
map切片:
0: 11 11 0
1: 1 2 1
2: 2 3 2
3: 5 5 2
存盘数据, 'd:/chessmap.data'
sparseArrObj 序列化后: [{"col":11,"row":11,"val":0},{"col":2,"row":1,"val":1},{"col":3,"row":2,"val":2},{"col":5,"row":5,"val":2}]
文件读取输出
oldData= [{"col":11,"row":11,"val":0},{"col":2,"row":1,"val":1},{"col":3,"row":2,"val":2},{"col":5,"row":5,"val":2}]
反序列化结果: [map[col:11 row:11 val:0] map[col:2 row:1 val:1] map[col:3 row:2 val:2] map[col:5 row:5 val: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 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
======================