稀疏数组的定义及代码实现

154 阅读4分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第5天,点击查看活动详情

定义

当一个数组的大多数元素相同时,可以使用稀疏数组来压缩该数组,缩小数组的大小.

具体的处理方式为:

  1. 记录原数组的总行数(总列数)
  2. 记录原数组的与大多数元素不相同的值
  1. 由1和2两步组成的一个新数组就称为稀疏数组

举例:

如下二维数组(3x5)

1,1,1,1,1
1,1,2,1,1
1,1,1,3,1

转换为稀疏数组:

  1. 总行数3 总列数5
  2. 不相同的值为 第二行第三列值为2 第三行第四列值为3
  1. 因此组成稀疏数组为:
行,列,值
3,5,2
2,3,2
3,4,3

其中第一行记录的时总行数总列数以及有效值的个数

下面两行记录的是不相同的值及在原数组中的位置

通过对比可以看出,经过稀疏数组转换 一个3x5的二维数组转换为了一个3x3的稀疏数组,缩小了数组的大小.

转换思路

在实际问题中,稀疏数组主要是为了解决数组过大,不易存储的问题,那么正常操作就是将数组压缩为稀疏数组存储,在使用的时候再将稀疏数组解析为数组使用.

所以在实际过程中我们就需要两个转换过程

  1. 数组转换为稀疏数组
    1. 获取数组中有效值的个数,所谓有效值,就是与大多数值不相同的值(比如上文中例子里的2,3),将有效值的个数记为sum
    2. 创建稀疏数组,数组的大小为 array[sum+1][3] sum+1是因为要加上总行数,总列数 3列就是行/列/值
    1. 将总行数/总列数,有效值的信息写入稀疏数组
  1. 稀疏数组反向解析为数组
    1. 根据总行数/总列数创建数组
    2. 根据有效值的行/列/值信息给数组赋值即可

代码实现

数组转换为稀疏数组

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("=====原数组=====");
    }

\

总结

  1. 学习到稀疏数组的定义
  2. 代码简单实现稀疏数组

其实就是将数组转换一下,将数组的值进行分类,将大部分相同的值归为一类,只记录不一样的值,从而减小数组的长度

\

但是这种压缩方式仅仅适合数组中有很多相同的值的情况,如果一个数组中所有的值都不一样,那这种方式就没有意义了

例如: 3x5的数组所有的值都不一样,根据上述算法,稀疏数组的大小为 [15+1]x[3] = 48 这样的情况就不能使用稀疏数组了,或者说茂密数组? 嘿嘿