稀疏数组使用场景
当一个二维数组的大部分元素为0,或者为相同值时,可以使用稀疏数组来压缩保存该二维数组。
稀疏数组处理方法
- 稀疏数组一般n行,3列,第一列表示原先二维数组的行,第二列表示原先二维数组的列,第三列表示值。
- 稀疏数组的第一行,一般用来表示原先二维数组的总行数以及总列数,值可以定义一个原先二维数组中不可能产生的值,比如-1,0。
简单的例子
- 原二维数组看做棋盘,白子为1,黑子为2。
- 稀疏数组第一行表示了”棋盘大小”为*77**,值为0,该值只是用于甄别其他有效值。
- 稀疏数组第二行至第四行表示了”棋盘”内白子黑子的分布,顺序为从上到下,从左到右。
- 可以将行和列看为x轴和y轴。
二维数组矩阵用稀疏数组表示(go语言思路)
- 每一个棋子有三个属性,x轴坐标,y轴坐标,颜色。一个棋子的属性可以用结构体来表示。
- 稀疏数组由于存在长度不确定性,所以使用切片的方式来表示。
- 稀疏数组的第一个元素围棋盘布局。
go代码对二维数组压缩保存为稀疏数组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
| package main
import "fmt"
func main() { var chessMap [7][7]int chessMap[1][1] = 1 chessMap[2][2] = 2 chessMap[2][4] = 1 chessMap[5][3] = 2
for _,v := range chessMap { for _,v2 := range v { fmt.Printf("%d\t",v2) } fmt.Printf("\n") }
type chess struct { axisX int axisY int value int }
var chessSparseMap []chess
firstLine := chess{ axisX: 7, axisY: 7, value: 0, }
chessSparseMap = append(chessSparseMap, firstLine)
for k,v := range chessMap { for k2,v2 := range v { if v2 != 0 { tmpChess := chess{ axisX:k, axisY:k2, value:v2, } chessSparseMap = append(chessSparseMap, tmpChess) } } } fmt.Println("稀疏数组为") fmt.Println(chessSparseMap)
}
output:
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 2 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 稀疏数组为 [{7 7 0} {1 1 1} {2 2 2} {2 4 1} {5 3 2}]
|
稀疏数组还原为二维数组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
| package main
import ( "fmt" "os" "bufio" "io" "strings" "strconv" )
func main() { type chess struct { axisX int axisY int value int }
var chessMap [7][7]int
file, err := os.Open("./learn-go/数据结构/1.稀疏数组/sparseMap") defer file.Close() if err != nil { fmt.Println("打开异常") return }
reader := bufio.NewReader(file) for { content, err := reader.ReadString('\n') if err != nil { fmt.Println("内容读取完毕") break }
if err == io.EOF { break } contentSlice := strings.Split(content," ")
axisX, err := strconv.Atoi(contentSlice[0]) if err != nil { fmt.Println("axisX转换出错") return }
axisY, err := strconv.Atoi(contentSlice[1]) if err != nil { fmt.Println("axisY转换出错") return } value, err := strconv.Atoi(strings.Split(contentSlice[2], "\r\n")[0]) if err != nil { fmt.Println("value转换出错",err) return }
if value != 0 { chessMap[axisX][axisY] = value } }
for _,v := range chessMap { for _, v2 :=range v{ fmt.Printf("%d \t",v2) } fmt.Println() } }
output:
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 2 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0
|
sparseMap文件内容
1 2 3 4 5 6
| 7 7 0 1 1 1 2 2 2 2 4 1 5 3 2
|