稀疏数组(SparseArray)(Go)
稀疏数组(SparseArray)介绍:
稀疏数组实质还是数组;由实际案例来引出:编写的五子棋程序中,由存盘退出和续上盘的功能;
当一个数组中大部分元素为0(或其他都是相同的数值)数组时,可以使用稀疏数组来保存该数组;
稀疏数组的处理方法是:
1.记录数组一共由几行几列,有多少个不同的值。
2.把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模;
稀疏数组 ----> 压缩数组
代码实现:
package main import ( "fmt" "bufio" "os" "io" "strings" "strconv" ) type ValNode struct { row int col int val int } func main() { // 稀疏数组 实际案例 五子棋 存盘退出,续上盘 //步骤1 创建原始二维数组 var oriMap [11][11]int oriMap[1][2] = 1 // 黑子 oriMap[2][3] = 2 // 白子 // 步骤2 遍历看原始二维数组 for _, v := range oriMap { for _, v2 := range v { fmt.Printf("%d\t", v2) } fmt.Println() } // 步骤3 转成稀疏数组 // 思路 // 1.遍历原二维数组 oriMap,如果我们发现有一个元素的值不为0,创建一个node结构体 // 2.将其放入到对应的切片即可; // 标准的一个稀疏数组应该还有一个 记录原始二维数组的规模(行和列,默认值) var sparseArray []ValNode valNode := ValNode{ row : 11, col : 11, val : 0, } sparseArray = append(sparseArray, valNode) for i, v := range oriMap { for j, v2 := range v { if v2 != 0 { // 创建一个ValNode 值节点 valNode := ValNode{ row : i, col : j, val : v2, } sparseArray = append(sparseArray, valNode) } } } filePath := "e:/chess_data.txt" file, err := os.OpenFile(filePath, os.O_WRONLY | os.O_CREATE, 0666) if err != nil { fmt.Println("open file err=", err) return } // 及时关闭file句柄 defer file.Close() // 写入时,使用带缓存的 *Writer writer := bufio.NewWriter(file) // 输出稀疏数组 fmt.Println("当前的稀疏数组为::::") for i, valn := range sparseArray { // 存盘 fmt.Printf("%d: %d %d %d \n", i, valn.row, valn.col, valn.val) // 写入到文件中 使用带缓冲的 str := fmt.Sprintf("%d %d %d\n", valn.row, valn.col, valn.val) fmt.Println("写入文件的内容:", str) writer.WriteString(str) } writer.Flush() // 续上盘 即恢复原始的数组 从文件读取 file, err = os.Open(filePath) if err != nil { fmt.Println("open file err=", err) } fmt.Println("file==",file) // 当函数退出时,要及时关闭file defer file.Close() // 续上盘 即恢复原始的数组 reader := bufio.NewReader(file) // 先创建一个原始数组 var chessMap [11][11]int // 循环的读取文件的内容 for { flag := true str, err := reader.ReadString('\n') // 读到一个换行就结束 if err == io.EOF { // io.EOF 表示文件的末尾 break } // 赋值 str = strings.Trim(str, "\n") fmt.Printf("%q \n", str) str_arry := strings.Split(str, " ") if str_arry[len(str_arry)-1] == "0" { // 第一行数据没有多大用处 在golang中 flag = false } if flag { row, err := strconv.Atoi(str_arry[0]) if err != nil { fmt.Println("str_arry[0] err", err) } col, err := strconv.Atoi(str_arry[1]) if err != nil { fmt.Println("str_arry[1] err", err) } val, err := strconv.Atoi(str_arry[2]) if err != nil { fmt.Println("str_arry[2] err", err) } chessMap[row][col] = val // fmt.Printf("%v %v %v \n", str_arry[0], str_arry[1], str_arry[2]) } } fmt.Println("文件读取完毕, 原始数组赋值完毕!") // 最后遍历chessMap 原始二维数组 for _, v := range chessMap { for _, v2 := range v { fmt.Printf("%d\t", v2) } fmt.Println() } }