稀疏数组
更多内容,前往 IT-BLOG
一、稀疏数组的定义
稀疏(sparsearray)数组:可以看做是普通数组的压缩,但是这里说的普通数组是值无效数据量远大于有效数据量的数组。
稀疏数组的应用场景:五子棋程序,有存盘退出和续上盘的功能,将五子棋盘转化成二维数组如下所示:
分析上述问题:因为该二维数组默认的地方值为0,因此记录了很多没有意义的数据。当遇到此种情况时,可以使用稀疏数组。
当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。稀疏数组的处理方法是:
■ 数组的第一行用于记录数组一共有几行几列,有多少个不同的值。
■ 把具有不同值的元素的行列记录在一个小规模的数组中,从而缩小程序的规模。
二、应用实例
我们将下图所示的棋盘使用稀疏数组进行存盘退出操作:
【1】将上面类似的二位数组棋盘保存到稀疏数组中,并存放至外部备份文件 sparsearray.text 中:稀疏数组可以简单的看作为是压缩,在开发中也会使用到。比如将数据序列化到磁盘上,减少数据量,在 IO 传输过程中提高效率等等。为什么要进行压缩:因为稀疏矩阵中存在大量的默认值,占据了大量的存储空间,而真正有用的数据却少之又少;且在计算时浪费资源,所以要进行压缩存储以节省存储空间和计算方便。
1 /** 2 * 将棋盘转化为稀疏数组并备份与外部设配 3 */ 4 public class Sparsearray { 5 //定义一个二维数组 6 public static void main(String[] args) throws Exception { 7 //定义成int类型的二维数组,默认值就为0; 8 int[][] intArr = new int[11][11]; 9 //根据棋盘中显示,存在一个黑子,我们用1表示,蓝子有2表示 10 intArr[1][2]=1; 11 intArr[2][3]=2; 12 13 /* 上述二维数组输出的矩阵图如下所示 14 0 0 0 0 0 0 0 0 0 0 0 15 0 0 1 0 0 0 0 0 0 0 0 16 0 0 0 2 0 0 0 0 0 0 0 17 0 0 0 0 0 0 0 0 0 0 0 18 0 0 0 0 0 0 0 0 0 0 0 19 0 0 0 0 0 0 0 0 0 0 0 20 0 0 0 0 0 0 0 0 0 0 0 21 0 0 0 0 0 0 0 0 0 0 0 22 0 0 0 0 0 0 0 0 0 0 0 23 0 0 0 0 0 0 0 0 0 0 0 24 0 0 0 0 0 0 0 0 0 0 0 25 */ 26 for (int i=0;i<intArr.length;i++){ 27 for(int j=0;j<intArr.length;j++){ 28 System.out.print("\t"+intArr[i][j]); 29 } 30 System.out.println(); 31 } 32 33 //将上面的二位数组,压缩成稀疏数组 34 int sum = 0; //不为零的个数 35 for(int[] row: intArr){ 36 for(int data : row){ 37 if(data != 0){ 38 sum++; 39 } 40 } 41 } 42 //创建一个稀疏数组, sum+1:表示第一行 + 不为零的值,第一行用于存放(行列值:3列数据) 43 int[][] sparseArray = new int[sum+1][3]; 44 sparseArray[0][0] = intArr.length; 45 sparseArray[0][1] = intArr[0].length; 46 sparseArray[0][2] = sum; 47 48 //创建一个变量,用于存放稀疏的行数 49 int num = 0; 50 //将原数组中不为零的值 存放到 稀疏数组中 51 for (int i=0;i<intArr.length;i++){ 52 for(int j=0;j<intArr.length;j++){ 53 if(intArr[i][j] != 0){ 54 ++num; 55 sparseArray[num][0]=i; 56 sparseArray[num][1]=j; 57 sparseArray[num][2]=intArr[i][j]; 58 } 59 } 60 } 61 62 /* 稀疏数组输出的矩阵图如下所示: 63 11 11 2 64 1 2 1 65 2 3 2 66 */ 67 System.out.println("====分隔符===="); 68 //文件输出 69 FileOutputStream file = new FileOutputStream("sparsearray.text"); 70 for(int[] row: sparseArray){ 71 for(int data : row){ 72 System.out.print("\t"+data); 73 file.write(String.valueOf(data+" ").getBytes()); 74 } 75 System.out.println(); 76 file.write("\n".getBytes()); 77 } 78 file.flush(); 79 } 80 }
【2】稀疏数组输出的 sparsearray.text 内容如下:
1 /** 2 * 将稀疏数组文件中的内容恢复至传统的二维数组棋盘 3 */ 4 public class SparseArrayClass { 5 public static void main(String[] args) throws Exception { 6 //读取 sparsearray.text 中的内容 7 FileInputStream fileInputStream = new FileInputStream("sparsearray.text"); 8 InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream); 9 BufferedReader bufferedReader = new BufferedReader(inputStreamReader); 10 //读取文件中的内容 先读取第一行的数据 11 String s1 = bufferedReader.readLine(); 12 //判断文件第一行是否有值,如果有值则获取,并创建棋盘数组 13 if(s1 != null){ 14 String[] split = s1.split(" "); 15 int[][] sparsearray = new int[Integer.valueOf(split[0])][Integer.valueOf(split[1])]; 16 //有多少个稀疏值,则遍历获取多少行 17 for(int i=1;i<=Integer.valueOf(split[2]);i++){ 18 String line = bufferedReader.readLine(); 19 //获取到的散列数组的1-n 行数据,将其赋值到棋盘数组中 20 String[] sparse = line.split(" "); 21 sparsearray[Integer.valueOf(sparse[0])][Integer.valueOf(sparse[1])]=Integer.valueOf(sparse[2]); 22 } 23 24 /* 将稀疏数组转化为棋盘数组如下: 25 0 0 0 0 0 0 0 0 0 0 0 26 0 0 1 0 0 0 0 0 0 0 0 27 0 0 0 2 0 0 0 0 0 0 0 28 0 0 0 0 0 0 0 0 0 0 0 29 0 0 0 0 0 0 0 0 0 0 0 30 0 0 0 0 0 0 0 0 0 0 0 31 0 0 0 0 0 0 0 0 0 0 0 32 0 0 0 0 0 0 0 0 0 0 0 33 0 0 0 0 0 0 0 0 0 0 0 34 0 0 0 0 0 0 0 0 0 0 0 35 0 0 0 0 0 0 0 0 0 0 0 36 */ 37 for (int[] i: sparsearray){ 38 for (int j:i){ 39 System.out.print("\t"+j); 40 } 41 System.out.println(); 42 } 43 } 44 } 45 }