关于稀疏数组的讲解和使用(附完整Java代码)

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("=====================================");
    }
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值