package main
import (
"encoding/json"
"fmt"
"os"
)
// 定义一个构造体保留原始矩阵的信息
type sparseNode struct {
Row int
Col int
Val int
}
// 定义一个构造体保留反序列化后矩阵的信息
type unSparseNode struct {
Row int
Col int
Val int
}
func main(){
//1. 定义一个原始矩阵
var arr [11][11]int
arr[1][2] = 1
arr[2][3] = 2
//2. 打印原始矩阵
for _, v1 := range arr{
for _, v2 := range v1{fmt.Printf("%d", v2)
}
fmt.Println()}
//3. 将原始矩阵转换为一个稠密矩阵
// 思路:// 定义一个切片用来作为稠密矩阵
// 稠密矩阵只保留原始矩阵的非凡信息:// 稠密矩阵的第一个元素保留矩阵的大小和默认值
// 稠密矩阵中保留原始矩阵中不是默认值的行、列、值的信息
// 定义一个稠密矩阵切片
var sparseArr []sparseNode
// 先保留稠密矩阵中第一个元素,即原始矩阵的大小和默认值
valNode := sparseNode{
Row: 11,
Col: 11,
Val: 0,
}
sparseArr = append(sparseArr, valNode)
// 接着保留原始矩阵中的非凡信息到稠密矩阵
for i, v1 := range arr{
for j, v2 := range v1{
if v2 != 0{
valNode := sparseNode{
Row: i,
Col: j,
Val: v2,
}
sparseArr = append(sparseArr, valNode)
}
}
}
// 打印稠密矩阵
for _, v := range sparseArr{fmt.Printf("%d %d %d\n", v.Row, v.Col, v.Val)
}
//4. 到这里就实现了原始矩阵转换稠密矩阵,依据理论利用能够将稠密矩阵落盘到文件或者通过网络发送给其他人
// 其中落盘的形式有多种,能够依照稠密矩阵间接落盘,或者将稠密矩阵进行序列化为 json 字符串落盘到文件
// 这里应用较为简单的序列化落盘形式实现,json 字符串既能够落盘,也能够网络传输
bytes, err := json.Marshal(&sparseArr)
if err != nil {panic(err)
}
//5. 打印序列化后的 JSON 字符串
fmt.Println(string(bytes))
//6. 到这里就能够将 JSON 字符串进行落盘或者网络传输了,这里先实现落盘存储
w, err := os.Create("sparseArr.json")
if err != nil {panic(err)
}
defer w.Close()
_, err = w.Write(bytes)
if err != nil {panic(err)
}
//------------------------ 还原稠密矩阵为原始矩阵 ------------------------------
//1. 关上磁盘文件读取数据
r, err := os.Open("sparseArr.json")
if err != nil {panic(err)
}
defer r.Close()
fileInfo, err := r.Stat()
if err != nil {panic(err)
}
buf := make([]byte, fileInfo.Size())
_, err = r.Read(buf)
if err != nil {panic(err)
}
//2. 反序列化 JSON 字符串,首先定义一个构造体 unSparseNode 用来保留反序列化数据
// 再定义一个切片存储反序列化后的所有数据
var unSparseArr []unSparseNode
err = json.Unmarshal(buf, &unSparseArr)
if err != nil {panic(err)
}
//3. 打印反序列化后的数据
fmt.Println(unSparseArr)
//4. 依据反序列化后的切片数据还原原始矩阵
// 在初始化二维数组的时候遇到了一个问题,就是在初始化的时候数组大小必须指定常量
// 如果哪位大神有其余思路欢送留言一起探讨,我临时就这样写死了
unArr := make([][11]int, unSparseArr[0].Row)
for i, v1 := range unSparseArr{
if i != 0 {unArr[v1.Row][v1.Col] = v1.Val
}
}
//5. 打印还原后的原始矩阵
for _, v1 := range unArr{
for _, v2 := range v1{fmt.Printf("%d", v2)
}
fmt.Println()}
}