开发者学堂课程【Go 语言核心编程 - 数据结构和算法:数据结构和算法-原始数组转稀疏数组(二)】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/627/detail/9829
数据结构和算法-原始数组转稀疏数组(二)
(4)做标准的稀疏数组
这样做有一个巨大的问题,就是没有做一个标准的稀疏数组,标准的行数组,前面应该还有整个这个数据,原始数据规模有多大,原先是几行几列的,前面大家知道他是往后面追,而且在之前11本身就是确定的,所以如果这要做一个标准的稀疏数组,输入如下代码:
//标准的一个稀疏数组还有一个 记录元素的二维数组的规模(行和列,默认值)
//创建一个 ValNode 值结点
valNode := ValNode{
row : 11,
col : 11,
val : 0,
}
apparseArr = append(sparseArr,valNode)
接着输入稀疏数组的代码,如下:
//输出稀疏数组
fmt.Println(
“
当前的稀疏数组是:::::“)
for i, valNode := range sparseArr {
fmt.Println(
“
%d: %d %d %d\n
”
, i, valNode.row, valNode.col,valNode.val)
}
运行一下上述代码,测试结果如下:
(5)对以上代码的小结
原始的数组是长这个样子的,将原始数组转成稀疏数组处理后,看变得非常小了,第一个结点是11110,第二个结点是121,第三个结点是222,会原先这么大一个速度,变得这么小了,其实在实际的开发中,大量存在着这种情况的,这种数组、,字符串有很多很多。
如果做一个程序员,脑海里面从来没这种思想,那是很失败的,为什么说有些程序员他的代码一跑起来又节省内存,速度还快,而且都很有灵魂,因为他是有想法的,你当然也能实现,就是多占点内存,速度稍微慢一点儿,但是做一个优秀的程序员,肯定要去想怎么样让它变得更小一点,对原先11乘11,现在一下就变成这么几个数据,而且都有用,这个好处对于像有些编程语言来说,这个行和列可以直接从这读取出来直接初始化一个新的二维数组,只是构念不行,看 Java 里边,还有 APP 里面,一旦自己把这个读出来,就知道原始规模是什么,而且还可以变化,假如原始模式以前是十乘十的也可以做,只是 Go 语言里面这样写死,所以它这有点基础用的不是特别好,还有别的办法,即用切片。
(6)存入问题的代码实现
那现在有了这个东西,要反过来适应它,要反过来把它存到磁盘里面,因为你的目标是希望将来存盘退出,那还得把它搞到这个磁盘里面去,然后等到别人保存恢复的时候,要把它重新读出来,再恢复成原来的这个数字。
这里面又得动脑筋,之前讲过怎么把一个数或把一个东西存到一个文件里面去,在 chapter14/filedemo03/main.go 中有以下代码:
package main
import (
“
fmt
”
“
io/ioutil
”
)
func main() {
//使用 ioutil.ReadFile 一次性将文件读取到位
file :=
“
d:/test.txt
”
content, err := ioutil.ReadFile(file)
if err != nil {
fmt.Printf(
“
read err=%v
”
, err)
}
//把读取到的内容显示到终端
fmt.Printf(
“
%v ,string(content)) //[]bye
fmt.Printf(
“
%v
”
, string(content)) //[]bye
//我们没有显式的 Open 文件,因此也不需要显式的 Close 文件
//因为,文件的 Open 和 Close 被封装到 ReadFile 函数内部
这是一次性写入,肯定不合理,不能用这个工具,肯定是一个一个、一行一行有效数据存入的。
打开文件 chapter14/filedemo04/main.go,其中有以下代码:
func main() {
//创建一个新文件,写入内容5句”hello,Gardon”
//1.打开文件d:/abc.txt
filePath :=
“
d:/abc.txt
”
file, err := os.OpenFile(filePath, os.O_WRONLY | os.O_CREATE,0666)
if err != nil {
fmt.Println(
“
open file err=%v\n
”
,err)
return
}
//没有及时关闭 file 句柄
defer file.Close()
//准备写入5句”hello,Gardon”
str :=
“
hello,Gardon\r\n
”
//\r\n表示换行
//写入时,使用带缓存的 *Write
writer := bufio.NewWriter(file)
for i := 0; i < 5; i++ {
writer.WriteString(str)
}
//因为 writer 是带缓存,因此在调用 WriteString 方法时,其实
//内容是先写入到缓存的,所以需要调用 Flush 方法,将缓存的数据
//真正写入到文件中去,否则文件中会没有数据!!!
writer。Flush()
}
也可以先建一个新文件,比如以上代码中的文件,注意后缀它是无所谓的,一般来讲,存东西一般是自己的一个文件格式中文件的一个后缀,这就相当于之前写的代码中,在不停的遍历稀疏数组,可以把其里面的”valNode.row, valNode.col, valNode.val”做成一串,用空格隔开,再把它保存进去,这个地方一保存进去过后,应该有思路了,找到 chapter14/filedemo04/main.go 位置,每有一个字符串,就写一行进去,一行后面再换一行,所以最后在数据库里边,应该是保存了一个东西,其实真正保存的数据应该是
chessMap.data ,再把它保存起来,在它里面的东西应该是这样的,如下图:
在压缩后的文件里,其实就这么点数据,那么下一步该做什么事情?经过一番这个折腾,把它保存到一个文件里面了,这个文件就是 chessMap.data ,也有别的方法,但是最好用这个,这就是最简单的方式放进去,放进去之后,这个就叫存盘退出,当需要把此东西再经过一系列的操作恢复到这个地方的时候,就是续盘退出,就是要把这个东西重新恢复回来,显然很简单,恢复的时候恢复到这个数组,那么稀疏数组在中间就意义不大了。
如果在遍历整个这个地图的时候,直接把它恢复成原始的速度,这是可以的,因为每遍历一行,就可以建一个,每遍历一次,就知道现在哪个是第一个数,哪一个是零,把它初始化就行了,
如下图: