基本介绍

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

稀疏数组的处理方式是:

  1. 记录数组一共有几行几列,有多少不同的值
  2. 把具有不同值的行列及值记录在一个小规模的数组中,从而缩小程序的规模

比如有下面这个数组:
image.png
我们可以看到该数组中有大量重复元素0,那么我们可以采用如下的方法进行存储。
image.png
我们重新定义一个n3的数组,其中n的看有多少值。第一行存储行数和列数以及默认值,如上是5行5列默认值是0,后续存储的就是具体的行列以及其对应的值。这样以来,我们就将55的数组压缩成了8*3。

继续看下面这个例子:
image.png

思路如下:

  1. 遍历二维数组(棋盘),将有不为0的值保存到稀疏数组中
  2. 遍历稀疏数组,将其保存到文件中
  3. 从文件中读取将其恢复成二维数组(棋盘)

代码如下:
(1)存盘

  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. )
  6. type node struct {
  7. row int
  8. col int
  9. value int
  10. }
  11. func main(){
  12. // 创建原始数据
  13. var chess [11][11]int
  14. chess[1][2] = 1
  15. chess[2][3] = 2
  16. // 打印一下原棋盘
  17. for _, v :=range chess{
  18. for _,v2 := range v{
  19. fmt.Printf("%d ",v2)
  20. }
  21. fmt.Println()
  22. }
  23. // 将原始数据的行列以及默认值保存到第一个位置
  24. var ret []node
  25. n := node{
  26. row: 11,
  27. col: 11,
  28. value: 0,
  29. }
  30. ret = append(ret,n)
  31. // 遍历原始数组,将值不为0的存进去
  32. for i, v :=range chess{
  33. for j,v2 := range v{
  34. if v2 != 0{
  35. node := node{
  36. row: i,
  37. col: j,
  38. value: v2,
  39. }
  40. ret = append(ret,node)
  41. }
  42. }
  43. fmt.Println()
  44. }
  45. // 将结果保存到文件中
  46. file, err := os.OpenFile("./chess.data", os.O_CREATE|os.O_APPEND|os.O_RDWR, 0644)
  47. if err != nil {
  48. fmt.Println("open file failed. err:",err)
  49. return
  50. }
  51. defer file.Close()
  52. for _,v := range ret{
  53. s := fmt.Sprintf("%d %d %d \n",v.row,v.col,v.value)
  54. _, err := file.WriteString(s)
  55. if err != nil {
  56. fmt.Println("write data failed.err:",err)
  57. }
  58. }
  59. }

(2)恢复

  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "io"
  6. "os"
  7. "strconv"
  8. "strings"
  9. )
  10. type node struct {
  11. row int
  12. col int
  13. value int
  14. }
  15. func main() {
  16. // 将结果保存到文件中
  17. file, err := os.Open("../digui/chess.data")
  18. if err != nil {
  19. fmt.Println("open file failed. err:",err)
  20. return
  21. }
  22. defer file.Close()
  23. reader := bufio.NewReader(file)
  24. count := 0
  25. var chessMap [11][11]int
  26. for{
  27. line ,err:= reader.ReadString('\n')
  28. if err == io.EOF{
  29. break
  30. }
  31. if err != nil {
  32. fmt.Println("read file failed. err:",err)
  33. }
  34. count ++
  35. if count != 1{
  36. line = strings.Trim(line,"\n")
  37. split := strings.Split(line, " ")
  38. i,_ := strconv.Atoi(split[0])
  39. j,_:=strconv.Atoi(split[1])
  40. value,_:=strconv.Atoi(split[2])
  41. chessMap[i][j] = value
  42. }
  43. }
  44. // 打印一下原棋盘
  45. for _, v :=range chessMap{
  46. for _,v2 := range v{
  47. fmt.Printf("%d ",v2)
  48. }
  49. fmt.Println()
  50. }
  51. }