目录
稀疏数组的定义
稀疏数组(sparse array)是一种只为数组中的非零元素分配内存的特殊类型数组,内存中存储 了稀疏数组中非零元素的下标和值。可以看做是普通数组的压缩,普通数组是值无效数据量远大于有效数据量的数组。
当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。
稀疏数组的处理方法是:
1)
记录数组一共有几行几列,有多少个不同的值
2)
把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模
稀疏数组案例
一个普通二维数组里面存在大量的无效数据的时候,我们可以使用稀疏数组对原数组进行压缩。如下图所示:
代码实现
实现功能一:给出一个普通二维数组,将其压缩为稀疏数组,然后存放到磁盘。
实现功能二:能够从磁盘读取到存在稀疏数组的文件,还原为二维数组。
功能一的代码如下:
package com.chtw.sparsearray;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class SparseArrayTest {
public static void main(String[] args) {
//定义一个普通二位数组,我们以图片中的数组为例
int array[][] = new int[7][7];
array[1][5] = 9;
array[2][2] = 5;
array[4][0] = 7;
array[5][4] = 4;
printArray(array);
//先要获取稀疏数组的长度
int sparseArrayLength = getSparseArrayLength(array);
//定义一个稀疏数组
int sparseArr[][] = new int[sparseArrayLength][3];
// 第一行,存放数组有多少行,多少列,有多少个非 0 值
sparseArr[0][0] = array.length;
sparseArr[0][1] = array[0].length;
sparseArr[0][2] = sparseArrayLength-1;//非零值就为稀疏数组的长度减一
//将其他值赋值到稀疏数组当中
fillSparseArray(array, sparseArr);
System.out.println("==================================================");
//打印稀疏数组
printArray(sparseArr);
//保存稀疏数组到本地
try {
saveSparseArray(sparseArr, "C:\\Users\\CHTW\\Desktop\\");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 打印数组的方法
* @param array
*/
public static void printArray(int array[][]) {
for (int[] row : array) {
for (int item : row) {
System.out.printf("%d\t", item);
}
System.out.println();
}
}
/**
* 获取稀疏数组的长度
* @param array 原二维数组
* @return 稀疏数组的长度
*/
public static int getSparseArrayLength(int array[][]) {
// 1. 计算一共有多少个非零值
int sum = 0;
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[i].length; j++) {
if (array[i][j] != 0)
sum++;
}
}
return sum+1;
}
/**
* 填充稀疏数组
* @param array 原二维数组
* @param sparseArr 稀疏数组
*/
public static void fillSparseArray(int array[][],int sparseArr[][]) {
int count = 0;
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[i].length; j++) {
if (array[i][j] != 0) {
count++;
sparseArr[count][0] = i;
sparseArr[count][1] = j;
sparseArr[count][2] = array[i][j];
}
}
}
}
/**
* 保存稀疏数组
* @param sparseArr 稀疏数组
* @param filePath 文件路径
* @throws FileNotFoundException
* @throws IOException
*/
public static void saveSparseArray(int sparseArr[][],String filePath) throws Exception {
File file = new File(filePath+"sparseArray.txt");
if(!file.exists()){
file.createNewFile();
}
FileOutputStream fos = new FileOutputStream(file);
for (int[] row : sparseArr) {
for (int item : row) {
fos.write((item+" ").getBytes());
}
fos.write("\n".getBytes());
}
System.out.println("保存成功");
fos.flush();
fos.close();
}
}
运行结果如下:
打开保存的文件,文件内容如下:
和我们的稀疏数组保持一致的。
功能二的实现代码如下:添加两个方法即可
/**
* 从文件读取稀疏数组
* @param filePath 文件路径
* @return
*/
public static int[][] readSparseArray(String filePath) throws Exception{
File file = new File(filePath);
FileInputStream in = new FileInputStream(file);
BufferedReader bfr=new BufferedReader(new InputStreamReader(in));
String data=null;
int count = 0;//计算稀疏数组的长度
String str="";//读取出来是字符串
try {
while((data=bfr.readLine())!=null){
str += data;
str += "\n";
count++;
}
} catch (IOException e) {
e.printStackTrace();
}
//定义一个int类型的二维数组,来装读取出来的数据
int sparseArray[][] = new int[count][3];
//按照分行将str分为多组数据
String strArr1[] = str.split("\n");
//遍历strArr1
for(int i =0;i<strArr1.length;i++) {
//同时将二级数组分裂出来
String strArr2[] = strArr1[i].split(" ");
//遍历strArr2,同时将数据填充到strArr
for(int j=0;j<strArr2.length;j++) {
sparseArray[i][j] = Integer.parseInt(strArr2[j]);
}
}
return sparseArray;
}
/**
* 恢复为原数组
* @param sparseArr
* @return
*/
public static int[][] restoreArray(int sparseArr[][]){
int chessArr[][] = new int[sparseArr[0][0]][sparseArr[0][1]];
for (int i = 1; i < sparseArr.length; i++) {
chessArr[sparseArr[i][0]][sparseArr[i][1]] = sparseArr[i][2];
}
return chessArr;
}
再main函数中添加代码测试:
输出结果为:
和原来的数据是保持一致的。