JAVA稀疏数组

引入

数组是一个很常见的数据存储模式,但是有时使用数组会浪费掉一部分空间;例如在5*5的五子棋中,黑子代表1,白子代表2,而空白的区域代表0;为了表示棋盘中的数据,我们可能会使用二维数组来解决这个问题,最后的结果如下
0 1 0 2 0
1 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
此时,在这个数组中,我们会浪费掉一些空间,因为这些空间表示的都是0;为了解决这个问题,避免浪费过多的空间,我们需要使用稀疏数组。

介绍

在稀疏数组中,每行分别有三个元素:行,列,值。在稀疏数组的第一行,行表示原数组的行数,列表示原数组的列数,值表示原数组非0数据的个数;接下来的稀疏数组的几行中,行表示非0数据所在原数组的行数,列表示非0数据所在原数组的列数,而值则代表此非0数据的值。

例子

还是刚才那个五子棋的例子。原数组是5*5的数组,数据如下
0 1 0 2 0
1 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
我们用稀疏数组来表示原数组
5 5 3
0 1 1
0 3 2
1 0 1
相比与原来的数组,稀疏数组的大小变小许多:原数组有25个元素,而稀疏数组只有12个。

实现稀疏数组

下面的程序包含5个函数,分别是:打印数组,压缩原数组为稀疏数组,将稀疏数组复原成原数组,把稀疏数组存储到硬盘,从硬盘中读取稀疏数组

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class SparsArrayStudy {
 public static void main(String[] args) {
  System.out.printf("\t原数组\n");
  int[][] array = new int[5][5];
  array[0][1] = 1;
  array[0][3] = 2;
  array[1][0] = 1;
  print(array);
  
  System.out.printf("\t压缩后的数组\n");
  int[][] SparseArray = compress(array);
  print(SparseArray);
  
  System.out.printf("\t原数组恢复\n");
  array = recovery(SparseArray);
  print(array);
  
  
  String source = "E:\\java程序\\hello-world\\src\\DataStructure\\SparseArray.data";
  System.out.println();
  System.out.println("\t将稀疏数组存入硬盘");
  store(SparseArray,source); //指定存储位置
  System.out.println();
  
  System.out.println("\t从硬盘中读取稀疏数组");
  SparseArray = read(source);//指定读取位置
  if(SparseArray!=null) {
   print(SparseArray);
  }
  
  
 }
 //原数组压缩成稀疏数组
 public static int[][] compress(int[][] array){
  //遍历数组
  int sum =0;
  for(int i=0;i<array.length;i++) {
   for(int j=0;j<array[0].length;j++) {
    if(array[i][j]!=0) {
     sum++;
    }
   }
  }
  
  int[][] SparseArray = new int[sum+1][3];
  SparseArray[0][0] = array.length;
  SparseArray[0][1] = array[0].length;
  SparseArray[0][2] = sum;
  int count = 1;
  for(int i=0;i<array.length;i++) {
   for(int j=0;j<array[0].length;j++) {
    if(array[i][j]!=0) {
     SparseArray[count][0] = i;
     SparseArray[count][1] = j;
     SparseArray[count][2] = array[i][j];
     count++;
    }
   }
  }
  return SparseArray;
  
 }
 
 //打印数组
 public static void print(int[][] array) {
  for(int i=0;i<array.length;i++) {
   for(int j=0;j<array[0].length;j++) {
    System.out.printf("%d\t",array[i][j]);
   }
   System.out.println();
  }
 }
 
 //把稀疏数组还原成原来数组
 public static int[][] recovery(int[][] SparseArray) {
  //创建原来的数组
  int[][] array = new int[SparseArray[0][0]][SparseArray[0][1]];
  //遍历压缩后的数组
  for(int i=1;i<SparseArray.length;i++) {
   array[SparseArray[i][0]][SparseArray[i][1]] = SparseArray[i][2];
  }
  return array;
 }
 
 //将稀疏数组存储到硬盘
 public static void store(int[][] SparseArray,String source){
  
  FileOutputStream file;
  try {
   file = new FileOutputStream(source,false);
   BufferedOutputStream buf = new BufferedOutputStream(file);
   for(int i=0;i<SparseArray.length;i++) {
    for(int j=0;j<SparseArray[0].length;j++) {
     buf.write(Integer.valueOf(SparseArray[i][j]).byteValue());
     buf.flush();
    }
   }
   buf.close();
   file.close();
  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  System.out.println("\t写入成功");
 }
 
 //从硬盘中读取稀疏数组
 public static int[][] read(String source) {
  
  FileInputStream file;
  int[][] SparseArray = null;
  try {
   file = new FileInputStream(source);
   BufferedInputStream buf = new BufferedInputStream(file);
   int row = buf.read();
   int column = buf.read();
   int sum = buf.read();
   SparseArray = new int[sum+1][3];
   SparseArray[0][0] = row;
   SparseArray[0][1] = column;
   SparseArray[0][2] = sum;
   
   for(int i=1;i<SparseArray.length;i++) {
    SparseArray[i][0]=buf.read();
    SparseArray[i][1]=buf.read();
    SparseArray[i][2]=buf.read();
   }
   buf.close();
  }catch(Exception e) {
   System.out.println("未找到文件");
  }
  return SparseArray;
 }
}

结果
在这里插入图片描述

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值