Go 稀疏数组学习与实现

13 篇文章 7 订阅

仍然还是一个数组

基本介绍

一般就是指二维以上的数组
当一个数组中大部分元素是0 ,或者为同一个值的数组时,可以使用系数数组来保存该数组.

稀疏数组的处理方法:

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SlBq9xxF-1677594413402)(…/…/images/Pasted%20image%2020230228201055.png)]
这就是一个六行七列的二维数组.
所以用一个n行三类的二维数组来记录这个数组
第一列是行数, 第二列是列数, 第三列是值
6 7 0
0 3 22
0 6 15

5 2 28

这里的6 7 0 记录的是这个二维数组有6 行7 列 的0 值
其余行记录不一样的值的位置

这是一种压缩
但是我们可以发现,一个数值会多出两个值(行列)来表示,所以如果有值的数,大于了原来数组的1/3 就得不偿失了

代码实现

一个二维数组转换成稀疏数组

package main  
  
//稀疏数组  
  
type ValueNode struct {  
   row int  
   col int  
   Val int  
}  
  
func main() {  
   // 创建一个原始的数组  
   var chessMap [11][11]int  
   chessMap[1][2] = 1  
   chessMap[2][3] = 2  
   // 1 代表黑子  
   //2 代表白子  
   //输出原始数组  
   for _, item1 := range chessMap {  
      for _, item2 := range item1 {  
         print(item2)  
      }  
      println()  
   }  
   // 转换成稀疏数组  
   /*  
      思路  
      1.遍历数组,如果发现有一个元素的值不是0 ,就创建一个node结构体  
      2.将其放入到对应的切片中就可以了  
   */  
   var SparseArr []ValueNode  
   //标准的稀疏数组要记录二维数组的行和列  
   valueNode := ValueNode{  
      row: 11,  
      col: 11,  
      Val: 0,  
   }  
   SparseArr = append(SparseArr, valueNode)  
  
   // 结构体切片  
   //还是要全部扫描一遍的  
   for i, item1 := range chessMap {  
      for j, item2 := range item1 {  
         if item2 != 0 {  
            // 创节点了  
            valueNode = ValueNode{  
               row: i,  
               col: j,  
               Val: item2,  
            }  
            SparseArr = append(SparseArr, valueNode)  
  
         }  
      }  
  
   }  
  
   // 输出稀疏数组  
   for i, valueNode := range SparseArr {  
      println(i, valueNode.row, valueNode.col, valueNode.Val)  
   }  
  
}

将稀疏数组输入到一个文件中

package main  
  
import (  
   "bufio"  
   "fmt"   "os")  
  
//稀疏数组  
  
type ValueNode struct {  
   row int  
   col int  
   Val int  
}  
  
func main() {  
   path := "./resources/class.data"  
   // 创建一个原始的数组  
   var chessMap [11][11]int  
   chessMap[1][2] = 1  
   chessMap[2][3] = 2  
   // 1 代表黑子  
   //2 代表白子  
   //输出原始数组  
   for _, item1 := range chessMap {  
      for _, item2 := range item1 {  
         print(item2)  
      }  
      println()  
   }  
  
   //Arr2Sparse(chessMap)  
   // 转换成稀疏数组  
   /*  
      思路  
      1.遍历数组,如果发现有一个元素的值不是0 ,就创建一个node结构体  
      2.将其放入到对应的切片中就可以了  
   */  
   var SparseArr []ValueNode  
   //标准的稀疏数组要记录二维数组的行和列  
   valueNode := ValueNode{  
      row: 11,  
      col: 11,  
      Val: 0,  
   }  
   SparseArr = append(SparseArr, valueNode)  
  
   // 结构体切片  
   //还是要全部扫描一遍的  
   for i, item1 := range chessMap {  
      for j, item2 := range item1 {  
         if item2 != 0 {  
            // 创节点了  
            valueNode = ValueNode{  
               row: i,  
               col: j,  
               Val: item2,  
            }  
            SparseArr = append(SparseArr, valueNode)  
  
         }  
      }  
  
   }  
  
   //输出稀疏数组  
   file, err := os.OpenFile(path, os.O_WRONLY, 0666)  
   if err != nil {  
      fmt.Println("文件打开失败", err)  
   }  
   defer file.Close()  
   for _, valueNode := range SparseArr {  
      s := fmt.Sprintf("%d %d %d\n", valueNode.row, valueNode.col, valueNode.Val)  
      write := bufio.NewWriter(file)  
      write.WriteString(s)  
      write.Flush()  
      if err != nil {  
         println("写入失败")  
      }  
   }  
  
}

稀疏数组变成二维数组

package main  
  
import (  
   "bufio"  
   "fmt"   "os")  
  
//稀疏数组  
  
type ValueNode struct {  
   row int  
   col int  
   Val int  
}  
  
func main() {  
   path := "./resources/class.data"  
   // 恢复原始的数组  
   // 打开稀疏数组的文件  
   //     文件转换成稀疏数组(切片)  
   var sparse []ValueNode  
  
   file, _ := os.Open(path)  
   defer file.Close()  
   r := bufio.NewReader(file)  
   for true {  
      line, _, err := r.ReadLine()  
      if err != nil {  
         break  
      }  
  
      str := string(line)  
      var (  
         num1 int  
         num2 int  
         num3 int  
      )  
  
      fmt.Sscanf(str, "%d %d %d", &num1, &num2, &num3)  
      //println(num1, num2, num3)  
      valnode := ValueNode{  
         row: num1,  
         col: num2,  
         Val: num3,  
      }  
      sparse = append(sparse, valnode)  
  
   }  
   //fmt.Println(sparse)  
   // 得到数据  
  
   //创建一个二维数组  
   chessMap := make([][]int, sparse[0].row)  
   for i := 0; i < sparse[0].row; i++ {  
      chessMap[i] = make([]int, sparse[0].col)  
   }  
   //fmt.Println(chessMap)  
  
   // 遍历稀疏数组  
   for _, valNode := range sparse {  
      //跳过第一个,不然会数组越界  
      if valNode.Val == 0 {  
         continue  
      }  
      /*  
         或者 if index !=0 {         chessMap[valNode.row][valNode.col] = valNode.Val         }      */      chessMap[valNode.row][valNode.col] = valNode.Val  
  
   }  
   // 输出恢复后的数据  
   for _, v := range chessMap {  
      for _, v2 := range v {  
         print(v2)  
      }  
      println()  
   }  
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值