1.概念
稀疏数组可以看做是普通数组的压缩,但是这里说的普通数组是值无效数据量远大于有效数据量的数组
例如一下数组:
=====================================
原始数组:
0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0
0 0 0 2 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 134 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 456 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
=====================================
可以压缩为如下的形式:
=====================================
稀疏数组:
11 11 4
1 2 1
2 3 2
4 6 134
6 8 456
=====================================
2。意义
好了,了解了稀疏数组的概念,那他为什么要怎么去做呢?
这是因为:
-
原数组中存在大量的无效数据,占据了大量的存储空间,真正有用的数据却少之又少
-
压缩存储可以节省存储空间以避免资源的不必要的浪费,在数据序列化到磁盘时,压缩存储可以提高IO效率
3.代码实现
3.1我们在代码中创建一个二维数组,赋值打印输出,Java代码如下:
//1.创建一个11维度的二维数组
int[][] array1 = new int[11][11];
//随机给二维数组元素赋值
array1[1][2] = 24;
array1[2][3] = 734;
array1[4][6] = 134;
array1[6][8] = 456;
System.out.println("=====================================");
System.out.println("原始数组:");
for (int i = 0; i < array1.length; i++) {
for (int j = 0; j < array1[i].length; j++) {
System.out.print(array1[i][j] + "\t");
}
System.out.print('\n');
}
运行以上代码,将输出:
=====================================
原始数组:
0 0 0 0 0 0 0 0 0 0 0
0 0 24 0 0 0 0 0 0 0 0
0 0 0 734 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 134 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 456 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
=====================================
3.2创建了以上二维数组后,我们想办法把原始数组用稀疏数组表示,即进行压缩。思想很简单,便利二维数组的每一个原始,进行索引和值的统计,注意:我们默认0是无效的原始,即只对非零的原始进行下表索引和数值的统计。
生成稀疏数组的Java代码如下:
//2.生成为稀疏数组并打印
int sum = 0;//定义统计原始二维数组的有效值的个数
for (int i = 0; i < array1.length; i++) {
for (int j = 0; j < array1[i].length; j++) {
//注意:我们默认0是无效的原始,即只对非零的原始进行下表索引和数值的统计。
if (array1[i][j] != 0){
sum ++;
}
}
}
System.out.println("=====================================");
System.out.println("值的个数为:" + sum);
int[][] array2 = new int[sum+1][3];
array2[0][0] = array1.length;
array2[0][1] = array1.length;
array2[0][2] = sum;
int count = 0;
for (int i = 0; i < array1.length; i++) {
for (int j = 0; j < array1[i].length; j++) {
if (array1[i][j] != 0){
count ++;
array2[count][0] = i;
array2[count][1] = j;
array2[count][2] = array1[i][j];
}
}
}
System.out.println("稀疏数组:");
for (int i = 0; i < array2.length; i++) {
for (int j = 0; j < array2[i].length; j++) {
System.out.print(array2[i][j] + "\t");
}
System.out.print('\n');
}
运行以上代码,可输出如下结果:
=====================================
值的个数为:4
稀疏数组:
11 11 4
1 2 24
2 3 734
4 6 134
6 8 456
=====================================
结合两个输出结果可以发现,稀疏数组之所以可以表示原始的二维数组,因为稀疏数组把二维数组中冗余的数组统统去掉了,只保留二维数组的
- 维度信息
- 有意义的数值(可自行定义,此次默认非零元素为有效元素)
如稀疏数组的第一行表头信息:11 11 4
,表示的是此二维数组共有11行11列,并且有4个有效元素,而1 2 24
表示的在原始数组中第1行第2列的元素值为24,其余的:
2 3 734
4 6 134
6 8 456
则一样的表示为行索引、列索引、元素数值
;
3.3生成了稀疏数组之后,可以很高效的保存原始二维数组的信息。当我们需要将稀疏数组还原为二维数组,有一下操作:
//3.还原为原始数组并打印
int[][] array3 = new int[array2[0][0]][array2[0][1]];
for (int i = 1; i <= array2[0][2]; i++) {
array3[array2[i][0]][array2[i][1]] = array2[i][2];
}
System.out.println("=====================================");
System.out.println("还原数组:");
for (int i = 0; i < array3.length; i++) {
for (int j = 0; j < array3[i].length; j++) {
System.out.print(array3[i][j] + "\t");
}
System.out.print('\n');
}
System.out.println("=====================================");
输出为:
=====================================
还原数组:
0 0 0 0 0 0 0 0 0 0 0
0 0 24 0 0 0 0 0 0 0 0
0 0 0 734 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 134 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 456 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
=====================================
比较原始数组,发现还原正确,至此我们完成了原始数组生成稀疏数组、稀疏数组还原二维数组的全部操作。完整代码如下,新建一个ArrayCompress.java
复制粘贴即可运行,最后,欢迎大家收藏关注并留言~笔芯
/**
* @author Rico_dds
* @date 2020.3.24
* @description 普通二维数组转换成稀疏数组,再将稀疏数组还原为普通二维数组;
*/
public class ArrayCompress {
public static void main(String[] args) {
//1.创建一个11维度的二维数组
int[][] array1 = new int[11][11];
array1[1][2] = 24;
array1[2][3] = 734;
array1[4][6] = 134;
array1[6][8] = 456;
System.out.println("=====================================");
System.out.println("原始数组:");
for (int i = 0; i < array1.length; i++) {
for (int j = 0; j < array1[i].length; j++) {
System.out.print(array1[i][j] + "\t");
}
System.out.print('\n');
}
//2.生成为稀疏数组并打印
int sum = 0;//定义统计原始二维数组的有效值的个数
for (int i = 0; i < array1.length; i++) {
for (int j = 0; j < array1[i].length; j++) {
//注意:我们默认0是无效的原始,即只对非零的原始进行下表索引和数值的统计。
if (array1[i][j] != 0){
sum ++;
}
}
}
System.out.println("=====================================");
System.out.println("值的个数为:" + sum);
int[][] array2 = new int[sum+1][3];
array2[0][0] = array1.length;
array2[0][1] = array1.length;
array2[0][2] = sum;
int count = 0;
for (int i = 0; i < array1.length; i++) {
for (int j = 0; j < array1[i].length; j++) {
if (array1[i][j] != 0){
count ++;
array2[count][0] = i;
array2[count][1] = j;
array2[count][2] = array1[i][j];
}
}
}
System.out.println("稀疏数组:");
for (int i = 0; i < array2.length; i++) {
for (int j = 0; j < array2[i].length; j++) {
System.out.print(array2[i][j] + "\t");
}
System.out.print('\n');
}
//3.还原为原始数组并打印
int[][] array3 = new int[array2[0][0]][array2[0][1]];
for (int i = 1; i <= array2[0][2]; i++) {
array3[array2[i][0]][array2[i][1]] = array2[i][2];
}
System.out.println("=====================================");
System.out.println("还原数组:");
for (int i = 0; i < array3.length; i++) {
for (int j = 0; j < array3[i].length; j++) {
System.out.print(array3[i][j] + "\t");
}
System.out.print('\n');
}
System.out.println("=====================================");
}
}