Go的数据结构(感谢韩老师)
创始人
2024-04-07 00:17:18

一 稀疏数组

1.1 先看一个实际的需求

编写的五子棋程序中,有存盘退出和续上盘的功能
在这里插入图片描述
因为该二维数组的很多值是默认值 0, 因此记录了很多没有意义的数据

1.2 稀疏数组基本介绍

当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。

稀疏数组的处理方法是:

记录数组一共有几行几列,有多少个不同的值
思想:把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模
使用稀疏数组,来保留类似前面的二维数组(棋盘、地图等等)

把稀疏数组存盘,并且可以从新恢复原来的二维数组数

1.3 稀疏数组举例说明

在这里插入图片描述

1.4 把数组转换为稀疏数组实现

思路分析:
在这里插入图片描述
代码实现:

package mainimport ("bufio""fmt""os"
)type ValNode struct {row intcol intval int
}func main() {filePath := "E:/golang开发学习/sparsearray.data"file, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE, 0666)if err != nil {fmt.Printf("open file err=%v\n", err)return}//及时关闭file句柄defer file.Close()// 1. 创建一个原始数组var chessMap [11][11]intchessMap[1][2] = 1chessMap[2][3] = 2// 2. 输出查看原始数组fmt.Println("原始数组为:")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{row: 11,col: 11,val: 0,}sparseArr = append(sparseArr, ValNode)for i, v := range chessMap {for j, v1 := range v {if v1 != 0 {// 创建一个ValNode 值节点ValNode.row = iValNode.col = jValNode.val = v1sparseArr = append(sparseArr, ValNode)}}}// 4. 输出稀疏数组fmt.Println("当前的稀疏数组是:")writer := bufio.NewWriter(file)for _, ValNode := range sparseArr {var s1 = fmt.Sprintf("%d %d %d\n", ValNode.row, ValNode.col, ValNode.val)writer.WriteString(s1)fmt.Printf("%s", s1)}writer.Flush()
}

运行结果

[Running] go run "e:\golang开发学习\go_pro\test.go"
原始数组为:
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	
当前的稀疏数组是:
11 11 0
1 2 1
2 3 2

1.5 把稀疏数组还原为原数组

坑点一:读取后是字符串需要,分割成字符串数组,这里通过Split但是数组最后一个多一个换行符号需要去掉。
坑点二:golang是无法直接在二维数组创建时传变量的。这个时候先声明一个二维切片。初始化二维切片后。填入初始值。
代码实现:

package mainimport ("bufio""fmt""io""os""strconv""strings"
)func main() {file, err := os.Open("E:/golang开发学习/sparsearray.data")if err != nil {fmt.Printf("打开文件出错:%v", err)}defer file.Close()reader := bufio.NewReader(file)str, err := reader.ReadString('\n')if err == io.EOF { //io.EOF 文件末尾fmt.Println("第一行 读取完毕")}// 分割字符串 通过空格arr := strings.Split(str, " ")m, _ := strconv.Atoi(arr[0])n, _ := strconv.Atoi(arr[1])v, err := strconv.Atoi(strings.Replace(arr[2], "\n", "", -1))if err != nil {// handle errorfmt.Println(err)os.Exit(2)}// golang是无法直接在二维数组创建时传变量的 var chessMap [m][n]int 不能成功var chessMap [][]intfor i := 0; i < m; i++ {arr1 := make([]int, n)            //创建一个一维切片chessMap = append(chessMap, arr1) //把一维切片,当作一个整体传入二维切片中}for i := 0; i < m; i++ {for j := 0; j < n; j++ {chessMap[i][j] = v}}for {str, err := reader.ReadString('\n') // 一次读到换行结束if err == io.EOF {                  //io.EOF 文件末尾break}//输出内容arr := strings.Split(str, " ")m, _ := strconv.Atoi(arr[0])n, _ := strconv.Atoi(arr[1])v, _ := strconv.Atoi(strings.Replace(arr[2], "\n", "", -1))chessMap[m][n] = v}fmt.Println("稀疏数组还原成原数组:")for _, v := range chessMap {for _, v2 := range v {fmt.Printf("%d\t", v2)}fmt.Println()}
}

相关内容

热门资讯

邮件服务器架构解析 通过实验学习使用WinWebMail软件搭建邮件服务器,结合局域网内的DNS服务器,实现内部网络中电...
6岁小孩哥饭桌祝酒词情商拉满 (来源:河北新闻网)转自:河北新闻网 【#6岁小孩哥饭桌...
加拿大多伦多举行第四届青少年冰... 中新网2月21日电 作为2026年多伦多“欢乐春节”系列活动之一,第四届多伦多青少年冰上春晚于当地时...
最新或2023(历届)对不起,... 不知道为什么,忽然好想大哭一场。有时觉得我自己真幼稚,也有时突显得好成熟,但最近发生的事情实在太多,...