前言
先看一个实际的需求:编写的五子棋程序中,有存盘退出和续盘恢复的功能:
1.需求分析:
分析按照原始的方式来的二维数组的问题,因为该二维数组的很多值是默认值 0, 因此记录了很多没有意义的数据。稀疏数组的处理方法是:
1) 记录数组一共有几行几列,有多少个不同的值 。
2) 把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模。
3) 把稀疏数组存盘,并且可以从新恢复原来的二维数组数。
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 _,j := range v {
fmt.Printf("%d\t",j)
}
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)
}
//将这个稀疏数组,存盘 d:/chessMap.txt
filePath := "d:/chessMap.txt"
file,err := os.OpenFile(filePath,os.O_WRONLY | os.O_CREATE,0666)
if err != nil {
fmt.Println("OpenFile err = ",err)
}
defer file.Close()
writer := bufio.NewWriter(file)
for _, valNode := range sparseArr {
writer.WriteString(fmt.Sprintf("%d %d %d\r\n",valNode.row,valNode.col,valNode.val))
}
//必须将缓冲区的数据写入文件,否则导致文件不会被写入
writer.Flush()
//如何恢复原始的数组
//1. 打开这个 d:/chessMap.data => 恢复原始数组.
file2,err := os.Open("d:/chessMap.txt")
if err != nil {
fmt.Println("file2 Open fail err = ",err)
}
defer file2.Close()
//创建一个reader
reader := bufio.NewReader(file2)
var sparseArr1 []ValNode
for {
str, err := reader.ReadString('\n')
if err == io.EOF { // io.EOF表示文件的末尾
break
}
//strings.Fields()返回将字符串按照空白分割的多个字符串。
//如果字符串全部是空白或者是空字符串的话,会返回空切片。
arr := strings.Fields(str)
valNode := ValNode{}
for i, _ := range arr {
in, err := strconv.Atoi(arr[i])//转成int类型
if err != nil {
return
}
switch i {
case 0:
valNode.row = in
case 1:
valNode.col = in
case 2:
valNode.val = in
}
}
sparseArr1 = append(sparseArr1, valNode)
}
// 将稀疏数组还原成二维数组
var chessMap2 [][]int
for i, v := range sparseArr {
if i == 0 {
for a := 0; a < v.row; a++ {
mm := make([]int, v.col)
chessMap2 = append(chessMap2, mm)
}
} else {
chessMap2[v.row][v.col] = v.val
}
}
//打印二维数组
fmt.Println(chessMap2)
for _, v := range chessMap2 {
for _, v1 := range v {
fmt.Printf("%d\t",v1)
}
fmt.Println()
}
}
代码执行结果如下:
当前的稀疏数组是:
0: 11 11 0
1: 1 2 1
2: 2 3 2
复盘结果为:
0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0
0 0 0 2 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0