关于稀疏数组的介绍以及使用案例
以具体的需求为例:
编写的五子棋程序中,有存盘退出和续上盘的功能
分析按照原始的方式来的二维数组的问题
思路:
当一个数组中大部分元素为0,或者为同一个值得数组时,可以使用
稀疏数组来保存该数组
处理方法是:
(1)记录数组一共有几行几列,有多少个不同的值
(2)思想:把具有不同值得元素的行列及值记录在一个小规模的数组中。从而缩小程序的规模稀疏数组举例说明。
以下代码实现:
package main
import (
"bufio"
"fmt"
"io"
"os"
"strconv"
"strings"
)
type ValNode struct {
row int
col int
val int
}
func main() {
//1.创建一个原始数组
var chessMap [11][11]int
chessMap[1][2] = 1 //黑子
chessMap[2][3] = 2 // 蓝子
//2.输出原始的数组
for _, v := range chessMap {
for _, v2 := range v {
fmt.Printf("%d\t", v2)
}
fmt.Println()
}
//3.转成一个稀疏数组。
//思路:
//(1)遍历chessMap,如果我们发现有一个元素的值不为0,创建
//一个node结构体
//(2)将其放入对应的结构体中
var sparseArr []ValNode
//标准的一个稀疏数组应该还有一个记录元素的二维数组的规模(行和列,默认值)
//创建一个ValNode 值结点
valNode := ValNode{
row: 11,
col: 11,
val: 0,
}
sparseArr = append(sparseArr, valNode)
for i, v := range chessMap {
for j, v2 := range v {
if v2 != 0 {
//创建一个ValNode 值节点
valNode := ValNode{
row: i,
col: j,
val: v2,
}
sparseArr = append(sparseArr, valNode)
}
}
}
//输出稀疏数组
fmt.Println("当前的稀疏数组........")
for i, valNode := range sparseArr {
fmt.Printf("%d: %d %d %d\n", i, valNode.row, valNode.col, valNode.val)
}
//4.将稀疏数组存盘 保存到文件中
fileName := "E:/work/src/github.lzj.com/稀疏数组/sparsearray/chessmap.data"
file, err := os.OpenFile(fileName, os.O_CREATE|os.O_WRONLY, 0755)
if err != nil {
fmt.Println("error", err)
os.Exit(1)
}
defer file.Close()
for _, chess := range sparseArr {
str := strconv.Itoa(chess.row) + "\t" + strconv.Itoa(chess.col) + "\t" + strconv.Itoa(chess.val)
_, err = file.WriteString(str + "\n") //按行把数据写进文件
if err != nil {
os.Exit(1)
}
}
fmt.Println("Data save sucess!")
//5.恢复原始的数组
//1.打开E:/chessmap.data =>恢复原始数组
//2.这里使用稀疏数组恢复
file1, err1 := os.Open(fileName)
if err1 != nil {
fmt.Println("ERROR err1 != nil")
os.Exit(1)
}
defer file1.Close()
//先创建一个原始数组
var chessMap2 [11][11]int //用切片实现更好
buf := bufio.NewReader(file1)
for {
line, isPrefix, err2 := buf.ReadLine() //按行读取
if err2 != nil {
if err2 != io.EOF {
fmt.Println("ERROR io EOF")
return
}
//读取到最后
break
}
if isPrefix { //一行数据字节太长
fmt.Println("a too long line")
return
}
str := strings.Fields(string(line)) //去掉空白字符切割成字符串数组
row_, _ := strconv.Atoi(str[0])
col_, _ := strconv.Atoi(str[1])
val_, _ := strconv.Atoi(str[2])
fmt.Println("chessmap:%d %d %d", row_, col_, val_)
if val_ != 0 {
chessMap2[row_][col_] = val_
}
}
//看看chessMap2 是不是恢复了
fmt.Println("恢复后的稀疏数组........")
for _, v := range chessMap2 {
for _, v2 := range v {
fmt.Printf("%d\t", v2)
}
fmt.Println()
}
}