数据结构--稀疏矩阵的一种实现

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()
    }
}

你可能感兴趣的:(golang数据结构)