GO数据结构(一)——稀疏数组

2023-04-16 14:59:12 浏览数 (1)

1. 稀疏数组

稀疏数组(sparsearray) 基本介绍: 当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。 本质上就是压缩数组。 稀疏数组的处理方法:  1. 记录数组一共有几行几列,有多少个不同的值。  2. 把具有不同值的元素的行列以及值,记录在一个小规模的数组中,从而缩小程序的规模。

1.1 实际问题(棋盘)

如下面的二维数组,我们可以假设成是一个棋盘,1代表白子,2代表黑子,现在我们要对其进行存盘以及续盘的操作,如果我们将整个数组都存起来,势必会造成内存的浪费,那么我们可以考虑使用稀疏数组来解决这个问题。

代码语言:javascript复制
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

1.1.1 存盘

代码语言:javascript复制
func writeSparse()  {
	// 定义一个结构体,用来存放稀疏矩阵的值
	type ValNode struct{
		row int		// 所在行
		col int		// 所在列
		val int		// 值
	}

	// 定义一个二维数组——棋盘
	// 其他都为0
	var chessMap [11][11]int
	chessMap[1][2] = 1
	chessMap[2][3] = 2

	// 定义一个切片
	var sparseArr []ValNode

	// 11行 11列 默认值为0
	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{
					row: i,
					col: j,
					val: v2,
				}
				sparseArr =append(sparseArr,valNode)
			}
		}
	}

	// 存到文件中 便于续盘
	filePath := "./数据结构/sparseArr.txt"
	file, err := os.OpenFile(filePath,os.O_WRONLY|os.O_CREATE,0666)
	// 第一个数字代表u(拥有者)权限,
	// 第二个数字代表g(群组)权限,
	// 第三个数字代表o(其他人)权限
	// 每一个数字都是通过4(表示r),2(表示w),1(表示x)三个数字相加得到的
	// rwx 对应4,2,1
	// 那么只读的权限用4表示[r--],
	// 读写用6(4 2)表示[rw-],
	// 读写加执行用7(4 2 1)表示[rwx]。
	if err != nil{
		fmt.Println("os.OpenFile err:",err)
		return
	}
	// 最终 关闭流
	defer file.Close()
	// 创建写缓冲区
	writer := bufio.NewWriter(file)
	// 取出棋子
	for _, valNode:=range sparseArr{
		str:=fmt.Sprint(valNode.row,valNode.col,valNode.val)
		// 写到缓存区中
		_, err := writer.WriteString(str "n")
		if err != nil{
			fmt.Println("writer.WriteString(str) err:",err)
			return
		}
	}
	// 刷新数据, 将缓冲区数据写入io writer
	writer.Flush()
}

1.1.2 续盘

代码语言:javascript复制
func readSparse()  {
	type ValNode struct {
		row int
		col int
		val int
	}
	var sparseArr []ValNode

	filePath := "./数据结构/sparseArr.txt"
	file, err := os.Open(filePath)
	if err != nil {
		fmt.Println("os.Open(filePath) err:", err)
		return
	}
	defer file.Close()
	// 创建读缓冲区
	reader := bufio.NewReader(file)
	// 读取信息
	for{
		// 读取delim之前的所有string数据
		str,err := reader.ReadString('n')
		if err==io.EOF { 	// io.EOF代表文件的末尾
			break
		}
		fmt.Println(str)
		// 返回将字符串按照空白
		//(unicode.IsSpace确定, 可以是一到多个连续的空白字符)
		// 分割的多个字符串。
		// 如果字符串全部是空白或者是空字符串的话,会返回空切片。
		arr := strings.Fields(str)
		valNode := ValNode{}
		for i, _ := range arr {
			in,err := strconv.Atoi(arr[i])
			if err != nil {
				return
			}
			// arr 中 第一个位置是row 第二个位置是col 第三个位置是val
			switch i {
			case 0:
				valNode.row = in
			case 1:
				valNode.col = in
			case 2:
				valNode.val = in
			}
		}
		sparseArr = append(sparseArr,valNode)
	}
	// 棋盘
	var chessMap [][]int
	//var chessMap [11][11]int
	for i, v := range sparseArr {
		if i == 0 {
			for a := 0; a < v.row; a   {
				mm := make([]int, v.col)
				chessMap = append(chessMap, mm)
			}
		} else {
			chessMap[v.row][v.col] = v.val
		}

	}
	fmt.Println(chessMap)
}

0 人点赞