Data structure — an implementation of sparse matrix

Time:2021-7-8
package main

import (
    "encoding/json"
    "fmt"
    "os"
)

//Define a structure to store the information of the original matrix
type sparseNode struct {
    Row int
    Col int
    Val int
}

//Define a structure to store the information of the deserialized matrix
type unSparseNode struct {
    Row int
    Col int
    Val int
}

func main(){
    //1. Define a primitive matrix
    var arr [11][11]int
    arr[1][2] = 1
    arr[2][3] = 2

    //2. Print the original matrix
    for _, v1 := range arr{
        for _, v2 := range v1{
            fmt.Printf("%d  ", v2)
        }
        fmt.Println()
    }

    //3. Transform the original matrix into a sparse matrix
    //Thinking:
    //A slice is defined as a sparse matrix
    //Sparse matrix only preserves the special information of the original matrix
    //The first element of a sparse matrix holds the size and default value of the matrix
    //The sparse matrix stores the information of rows, columns and values that are not the default values in the original matrix
    //Define a sparse matrix slice
    var sparseArr []sparseNode
    //First, save the first element in the sparse matrix, that is, the size and default value of the original matrix
    valNode := sparseNode{
        Row: 11,
        Col: 11,
        Val: 0,
    }
    sparseArr = append(sparseArr, valNode)
    //Then the special information in the original matrix is saved to the sparse matrix
    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)
            }
        }
    }
    //Print sparse matrix
    for _, v := range sparseArr{
        fmt.Printf("%d  %d  %d\n", v.Row, v.Col, v.Val)
    }

    //4. The original matrix is transformed into sparse matrix. According to the practical application, the sparse matrix can be put into a file or sent to other people through the network
    //There are many ways to drop disk. You can drop disk directly according to sparse matrix, or serialize sparse matrix into JSON string to drop disk to file
    //Here, we use a more complex way of serializing the drop disk. The JSON string can not only drop disk, but also be transmitted over the network
    bytes, err := json.Marshal(&sparseArr)
    if err != nil {
        panic(err)
    }
    //5. Print the serialized JSON string
    fmt.Println(string(bytes))
    //6. Here, you can drop the JSON string to disk or transfer it to the network. Here, drop the string to disk first
    w, err := os.Create("sparseArr.json")
    if err != nil {
        panic(err)
    }
    defer w.Close()
    _, err = w.Write(bytes)
    if err != nil {
        panic(err)
    }

    //------------------------Restore sparse matrix to original matrix------------------------------
    //1. Open the disk file to read the data
    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. To deserialize the JSON string, first define a structure unsparsenode to store the deserialized data
    //Define a slice to store all the data after deserialization
    var unSparseArr []unSparseNode
    err = json.Unmarshal(buf, &unSparseArr)
    if err != nil {
        panic(err)
    }
    //3. Print the data after deserialization
    fmt.Println(unSparseArr)
    //4. Restore the original matrix according to the slice data after deserialization
    //When initializing a two-dimensional array, we encounter a problem that the size of the array must be specified as a constant
    //If any great God has other ideas, please leave a message to discuss them together. I'm dead for the moment
    unArr := make([][11]int, unSparseArr[0].Row)
    for i, v1 := range unSparseArr{
        if i != 0 {
            unArr[v1.Row][v1.Col] = v1.Val
        }
    }
    //5. Print the original matrix after restoration
    for _, v1 := range unArr{
        for _, v2 := range v1{
            fmt.Printf("%d  ", v2)
        }
        fmt.Println()
    }
}