Java二维数组与稀疏数组相互转换实现详解

 更新时间:2022年09月26日 08:37:31   作者:小黎的培培笔录  
在某些应用场景中需要大量的二维数组来进行数据存储,但是二维数组中却有着大量的无用的位置占据着内存空间,稀疏数组就是为了优化二维数组,节省内存空间

一、稀疏数组

1、什么是稀疏数组

当一个数组中大部分元素为0,或者为同一个值的数组时,可以用稀疏数组来保存该数组。稀疏数组,记录一共有几行几列,有多少个不为零的值或相同的值。

简单来说就是将大规模的数组缩小成小规模的数据,从而减少空间浪费。

2、图示

上面的图示中,左侧是二维数组,右侧是稀疏数组,将二维数组转成稀疏数组,明显的可以看出空间减少了,可以有效的节约空间,提高效率。那么二维数组怎么生成稀疏数组呢?其实很简单,因为二维数组有特定的格式,按格式将二维数组中的数据放入稀疏数组即可。

3、稀疏数组的表达方式

稀疏数组的列是固定的,只有三列,第一列表示二维数组的行,第二列表示二维数组的列,第三列表示二维数组非零数的个数。稀疏数组的第一行是固定的,用来表示总行数,总列数,总个数。其余行数根据个数而定。

二、二维数组→稀疏数组

根据上图所示:

第一步:创建二维数组

//首先创建二维数组
int[][] ChessArr1 = new int[11][11];
//赋值
ChessArr1[1][2] = 1;
ChessArr1[2][3] = 2;
//循环遍历得到非零个数
int num = 0;
for(int[] row : ChessArr1) {
   for(int data : row) {
       if(data != 0) {
           num++;
        }
   }
}

上面用到了增强for循环,第一个增强for循环表示每一个row代表一行(二维数组的行)也就相当与一维数组,第二个增强for循环再遍历一维数组得到每一个数据data来进行判断是否是非零数。

第二步:创建稀疏数组,并赋值

int[][] SparseArr = new int[num + 1][3];
//第一行赋值
SparseArr[0][0] = 11;
SparseArr[0][1] = 11;
SparseArr[0][2] = num;

前面分析的时候说了,第一行是固定的,二维数组的大小是知道的,所以行列的总数可以直接赋值,总有效个数也求了,也可以直接赋值。

第三步:遍历二维数组并赋值给稀疏数组

        int count = 0;
        for(int i = 0; i < 11; i++) {
            for(int j = 0; j < 11; j++) {
                if(ChessArr1[i][j] != 0) {
                    count++;
                    SparseArr[count][0] = i;
                    SparseArr[count][1] = j;
                    SparseArr[count][2] = ChessArr1[i][j];
                }
            }
        }

遍历二维数组,判断条件是这个数不等于零,此处需要一个计数变量,每符合一个非零数,计数变量就加一,可以用来表示稀疏数组的第几行,稀疏数组的列数是固定的,所以找到后直接进行赋值操作。

最后打印稀疏数组即可。

完整代码

        //首先创建二维数组
        int[][] ChessArr1 = new int[11][11];
        //赋值
        ChessArr1[1][2] = 1;
        ChessArr1[2][3] = 2;
        //将原始数组转 换成 稀疏数组
        //1、先遍历原始数组得到非0数的个数
        int num = 0;
        for(int[] row : ChessArr1) {
            for(int data : row) {
                if(data != 0) {
                    num++;
                }
            }
        }
        //2、创建 稀疏数组
        int[][] SparseArr = new int[num + 1][3];
        //3、第一行赋值
        SparseArr[0][0] = 11;
        SparseArr[0][1] = 11;
        SparseArr[0][2] = num;
        //4、循环赋非0值
        int count = 0;
        for(int i = 0; i < 11; i++) {
            for(int j = 0; j < 11; j++) {
                if(ChessArr1[i][j] != 0) {
                    count++;
                    SparseArr[count][0] = i;
                    SparseArr[count][1] = j;
                    SparseArr[count][2] = ChessArr1[i][j];
                }
            }
        }
        //5、打印稀疏数组
        System.out.println("\n===打印稀疏数组===");
        for(int[] row : SparseArr) {
            for(int data : row) {
                System.out.printf("%d\t",data);
            }
            System.out.println();
        }

三、稀疏数组→二维数组

第一步:创建新的二维数组

//1、定义一个新的二维数组
int[][] ChessArr2 = new int[SparseArr[0][0]][SparseArr[0][1]];

二维数组的大小来自稀疏数组的第一行第一列和第一行第二列,也就是 SparseArr[0][0] 和 SparseArr[0][1] ;初始状态下的二维数组数据全为零。

第二步:循环遍历并赋值

        //2、赋值
        for(int i = 1; i <= SparseArr[0][2]; i++) {
            ChessArr2[SparseArr[i][0]][SparseArr[i][1]] = SparseArr[i][2];
        }

因为除了少数是有效个数,其他全是零,所以我们只需要遍历有效个数。i 表示第几个有效个数也表示当前这个数在稀疏数组中的行,如上图所示:如 i = 1,表示在稀疏数组的第一行,它在二维数组中的位置为 (1,2),数值为 1 ;所以行和列分别是SparseArr[1][0]和SparseArr[1][1],数值为SparseArr[1][2]。

所以赋值表达式为:ChessArr2[SparseArr[i][0]][SparseArr[i][1]] = SparseArr[i][2]。

完整代码

        //将稀疏数组 转换成 二维数组
        //1、定义一个新的二维数组
        int[][] ChessArr2 = new int[SparseArr[0][0]][SparseArr[0][1]];
        //2、赋值
        for(int i = 1; i <= SparseArr[0][2]; i++) {
            ChessArr2[SparseArr[i][0]][SparseArr[i][1]] = SparseArr[i][2];
        }
        //3、打印新的二维数组
        System.out.println("\n===新的二维数组===");
        for(int[] row : ChessArr2) {
            for(int data : row) {
                System.out.printf("%d\t",data);
            }
            System.out.println();
        }

到此这篇关于Java二维数组与稀疏数组相互转换实现详解的文章就介绍到这了,更多相关Java二维数组与稀疏数组转换内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Idea打不了断点如何解决

    Idea打不了断点如何解决

    这篇文章主要介绍了Idea打不了断点如何解决的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • JAVA设计模式---原型模式你了解吗

    JAVA设计模式---原型模式你了解吗

    这篇文章主要介绍了JAVA 原型模式的的相关资料,文中讲解非常细致,实例帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2021-09-09
  • java实现快速打字游戏

    java实现快速打字游戏

    这篇文章主要为大家详细介绍了java实现快速打字游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-07-07
  • springboot的缓存技术的实现

    springboot的缓存技术的实现

    这篇文章主要介绍了springboot的缓存技术的实现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-05-05
  • 小议Java中@param注解与@see注解的作用

    小议Java中@param注解与@see注解的作用

    这篇文章主要介绍了Java中@param注解与@see注解的作用,注解的功能类似于通常代码中的注释,需要的朋友可以参考下
    2015-12-12
  • 利用Java计算某个日期是星期几

    利用Java计算某个日期是星期几

    不知道大家有没有遇到过同样的问题,谁谁的生日又要到了,看看是星期几?每年都要遇到好几次,所以想索性利用Java写个小工具,一次查询某具体日期在n年中分别是星期几。这样不就方便了吗?本文里给出了详细的示例代码,感兴趣的朋友们下面来一起看看吧。
    2016-10-10
  • 浅谈JSONObject的使用及示例代码(JSON解析)

    浅谈JSONObject的使用及示例代码(JSON解析)

    这篇文章主要介绍了浅谈JSONObject的使用及示例代码(JSON解析),本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-01-01
  • 深入了解java Lombok的使用方法

    深入了解java Lombok的使用方法

    这篇文章主要介绍了深入了解java Lombok的使用,Lombok是一个通过注解以达到减少代码的Java库,如通过注解的方式减少get,set方法,构造方法等,需要的朋友可以参考下
    2019-06-06
  • 举例讲解Java中的多线程编程

    举例讲解Java中的多线程编程

    这篇文章主要介绍了举例讲解Java中的多线程编程,线程是Java学习中的重要知识,需要的朋友可以参考下
    2015-09-09
  • 详细解读spring中的@Resource注解

    详细解读spring中的@Resource注解

    这篇文章主要介绍了详细解读spring中的@Resource注解,此注解来源于JSR规范(Java Specification Requests),其作用是找到依赖的组件注入到应用来,它利用了JNDI技术查找所需的资源,需要的朋友可以参考下
    2023-10-10

最新评论