一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第5天,点击查看活动详情。
定义
当一个数组的大多数元素相同时,可以使用稀疏数组来压缩该数组,缩小数组的大小.
具体的处理方式为:
- 记录原数组的总行数(总列数)
- 记录原数组的与大多数元素不相同的值
- 由1和2两步组成的一个新数组就称为稀疏数组
举例:
如下二维数组(3x5)
1,1,1,1,1
1,1,2,1,1
1,1,1,3,1
转换为稀疏数组:
- 总行数3 总列数5
- 不相同的值为 第二行第三列值为2 第三行第四列值为3
- 因此组成稀疏数组为:
行,列,值
3,5,2
2,3,2
3,4,3
其中第一行记录的时总行数总列数以及有效值的个数
下面两行记录的是不相同的值及在原数组中的位置
通过对比可以看出,经过稀疏数组转换 一个3x5的二维数组转换为了一个3x3的稀疏数组,缩小了数组的大小.
转换思路
在实际问题中,稀疏数组主要是为了解决数组过大,不易存储的问题,那么正常操作就是将数组压缩为稀疏数组存储,在使用的时候再将稀疏数组解析为数组使用.
所以在实际过程中我们就需要两个转换过程
- 数组转换为稀疏数组
-
- 获取数组中有效值的个数,所谓有效值,就是与大多数值不相同的值(比如上文中例子里的2,3),将有效值的个数记为sum
- 创建稀疏数组,数组的大小为 array[sum+1][3] sum+1是因为要加上总行数,总列数 3列就是行/列/值
-
- 将总行数/总列数,有效值的信息写入稀疏数组
- 稀疏数组反向解析为数组
-
- 根据总行数/总列数创建数组
- 根据有效值的行/列/值信息给数组赋值即可
代码实现
数组转换为稀疏数组
public static int[][] arrayToSparseArray() {
// 初始化原数组
// 0,0,0,0,0
// 0,0,2,0,0
// 0,0,0,3,0
int sourceArray[][] = new int[3][5];
sourceArray[1][2] = 2;
sourceArray[2][3] = 3;
// 输出原数组
System.out.println("=====原数组=====");
for (int[] ints : sourceArray) {
for (int anInt : ints) {
System.out.printf("%d\t", anInt);
}
System.out.println();
}
System.out.println("=====原数组=====");
// 转换稀疏数组
// 1.获取有效数个数
int sum = 0;
for (int[] ints : sourceArray) {
for (int anInt : ints) {
if (anInt != 0) {
sum++;
}
}
}
System.out.printf("====有效数的个数为%d",sum);
// 2. 创建稀疏数组
int sparseArray[][] = new int[sum+1][3];
// 3. 稀疏数组辅助
// 总行数/总列数/有效值个数
sparseArray[0][0] = sourceArray.length;
sparseArray[0][1] = sourceArray[0].length;
sparseArray[0][2] = sum;
// 有效值信息赋值
int count = 0;
for (int i = 0, sourceArrayLength = sourceArray.length; i < sourceArrayLength; i++) {
int[] ints = sourceArray[i];
for (int j = 0; j < ints.length; j++) {
int anInt = ints[j];
if (anInt != 0) {
count++;
sparseArray[count][0] = i;
sparseArray[count][1] = j;
sparseArray[count][2] = anInt;
}
}
}
System.out.println();
// 输出稀疏数组
System.out.println("=====稀疏数组=====");
for (int[] ints : sparseArray) {
for (int anInt : ints) {
System.out.printf("%d\t", anInt);
}
System.out.println();
}
System.out.println("=====稀疏数组=====");
return sparseArray;
}
稀疏数组反向解析为数组
public static void sparseArrayToArray(int[][] sparseArray){
// 输出稀疏数组
System.out.println("=====稀疏数组=====");
for (int[] ints : sparseArray) {
for (int anInt : ints) {
System.out.printf("%d\t", anInt);
}
System.out.println();
}
System.out.println("=====稀疏数组=====");
// 1.根据稀疏数组创建数组
int sourceArray[][] = new int[sparseArray[0][0]][sparseArray[0][1]];
// 2.将有效值赋值给原数组
for (int i = 1; i < sparseArray.length; i++) {
sourceArray[sparseArray[i][0]][sparseArray[i][1]] =
sparseArray[i][2];
}
System.out.println("=====原数组=====");
for (int[] ints : sourceArray) {
for (int anInt : ints) {
System.out.printf("%d\t", anInt);
}
System.out.println();
}
System.out.println("=====原数组=====");
}
\
总结
- 学习到稀疏数组的定义
- 代码简单实现稀疏数组
其实就是将数组转换一下,将数组的值进行分类,将大部分相同的值归为一类,只记录不一样的值,从而减小数组的长度
\
但是这种压缩方式仅仅适合数组中有很多相同的值的情况,如果一个数组中所有的值都不一样,那这种方式就没有意义了
例如: 3x5的数组所有的值都不一样,根据上述算法,稀疏数组的大小为 [15+1]x[3] = 48 这样的情况就不能使用稀疏数组了,或者说茂密数组? 嘿嘿