稀疏数组与二维数组之间的转换(详细带解说,能看懂能跟着敲出来)

本文介绍了稀疏数组的概念,展示了如何从二维数组中提取非0数据并转换为稀疏数组以节省存储空间。同时,还演示了如何将稀疏数组恢复为二维数组的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

稀疏数组介绍:
稀疏数组:当一个数组中大部分元素为同一个值时,就可以考虑使用稀疏数组来保存数据节省空间。
稀疏数组的原理:
  1)稀疏数组一共三列,第一行的第一列保存原二维数组的行数,第一行第二列保存原二维数组的列数,第一行第三列保存原二维数组非0数据的个数;
  2)稀疏数组一共有【原二维数组非0个数+1】行,第一行保存原二维数组整体信息,其余行数保存非0数据的具体信息:第一列保存数据的行数,第二列保存数据的列数,第三列保存数据的值。

以下是两个数据图,我们将对这两个数组进行相互转换:

完整代码:

/**
 * ClassName: SpareArray
 * Package: datas
 * Description:
 *
 * @Author 洛神
 * @Create 2024/3/14 下午 11:46
 * @vERSION 1.0
 */
public class SpareArray {
    public static void main(String[] args) {
        //创建一个原始的二维数组
        //0:没有棋子;1:黑子;2:蓝子
        int chessArr1[][] = new int[11][11];
        chessArr1[1][2] = 1;
        chessArr1[2][3] = 2;
        //输出原始的二维数组
        for (int[] row:chessArr1) {
            for (int data:row) {
                System.out.printf("%d\t",data);
            }
            System.out.println();
        }
        //将二维数组转稀疏数组
        //1.先遍历二维数组 得到非0数据的个数
        int sum = 0;
        for(int[] row:chessArr1){
            for(int data:row){
                if(data != 0){
                    sum++;
                    
                }
            }
        }
        System.out.println(sum);
        //2.
        // 创建对应的稀疏数组
        int sparseArr[][] = new int[sum+1][3];
        //给稀疏数组赋值
        sparseArr[0][0] = 11;
        sparseArr[0][1] = 11;
        sparseArr[0][2] = 2;
        //遍历二维数组,将非0的值存放到稀疏数组
        int loop=0;
        for (int i = 0; i < 11; i++) {
            for (int j = 0; j < 11; j++) {
                if(chessArr1[i][j]!=0){
                    loop++;
                    //因为列固定,行随非0数字的更新而不同,找到两者之间的规律建立联系
                    sparseArr[loop][0]=i;
                    sparseArr[loop][1]=j;
                    sparseArr[loop][2]=chessArr1[i][j];

                }
            }
        }
        System.out.println("==================================");
        for (int i = 0; i < sparseArr.length; i++) {
            System.out.println(sparseArr[i][0]+"\t"+sparseArr[i][1]+"\t"+sparseArr[i][2]);
        }
        //将稀疏数组恢复成二维数组
        //1.先读取稀疏数组第一行的数据由此创建二维数组
        int[][] td =new int[sparseArr[0][0]][sparseArr[0][1]];

        for (int i = 1; i < sparseArr.length; i++) {
            td[sparseArr[i][0]][sparseArr[i][1]]=sparseArr[i][2];
        }
        System.out.println("***********************************************");
        for (int i = 0; i < td.length; i++) {
            for (int j = 0; j < td[0].length; j++) {
                System.out.printf("%d\t",td[i][j]);
            }
            System.out.println();
        }

    }
}

代码分析:

1.创建二维数组信息:
 
int chessArr1[][] = new int[11][11];
        chessArr1[1][2] = 1;
        chessArr1[2][3] = 2;
        //输出原始的二维数组
        for (int[] row:chessArr1) {
            for (int data:row) {
                System.out.printf("%d\t",data);
            }
            System.out.println();
        }

   输出效果:

2.二维数组 ————> 稀疏数组

        2.1二维数组的行列数知道,遍历二维数组找出非0数据的个数。创建稀疏数组。
        这里使用了增强for循环。for(int[] row:chessArr1) 其中:int[]为循环的数据的数据类型,row为自定义变量名,chessArr1为要循环的数据

int sum = 0;
        for(int[] row:chessArr1){
            for(int data:row){
                if(data != 0){
                    sum++;
                    
                }
            }
        }

        2.2创建稀疏数组并给第一行赋值
          稀疏数组的列数为三列是固定的。行数为非0数据的个数+1,因为第一行存放二维数组整体信息,其他每行对应非0数据的具体信息
          稀疏数组第一行整体信息具体为:sparseArr[0][0]的值为二维数组的行数,sparseArr[0][1]的值为二维数组的列数,sparseArr[0][2]为二维数组非0数据的个数

// 创建对应的稀疏数组
        int sparseArr[][] = new int[sum+1][3];
        //给稀疏数组赋值
        sparseArr[0][0] = 11;
        sparseArr[0][1] = 11;
        sparseArr[0][2] = 2;

        2.3我们已经知道了二维数组非0数据的个数,现在我们要遍历二维数组找到非0数据的具体行列数信息存入稀疏数组。
        2.3.1当第一个非0数据出现时,我们当然知道将信息保存在稀疏数组的第二行,但是在循环中,第二个、第三个、...数据出现时呢?这样操作只会不断更新稀疏数组第二行的数据,但之前非0数据的信息并未保存下来。因此,我们不能将数据存放的位置写死,要找出非0数据的位置信息与稀疏数组的位置信息的规律,将二者联系起来。
        2.3.2当第一个非0数据出现时,我们将信息存放在稀疏数组的第二行,当第二个非0数据出现时,我们将信息存放在稀疏数组的第三行,以此类推...我们找出的规律是:将第n个出现的数据保存在稀疏数组的第n+1行
        2.3.3我们要创建一个变量显示这是第几个非0数据,并且这个变量+1后也将成为稀疏数组的行数。
        2.3.4赋值对应关系:第一个非0数据出现,loop+1,稀疏数组第2行的第1列保存第1个非0数据的行数,稀疏数组第2行的第2列保存第1个非0数据的列数,稀疏数组第2行的第3列保存第1个非0数据的值,至此,第一个非0数据信息保存完毕。当第二个非0数据出现,也根据上述关系保存。
3.5至此,稀疏数组创建并赋值完成。

int loop=0;
        for (int i = 0; i < 11; i++) {
            for (int j = 0; j < 11; j++) {
                if(chessArr1[i][j]!=0){
                    loop++;
                    //因为列固定,行随非0数字的更新而不同,找到两者之间的规律建立联系
                    sparseArr[loop][0]=i;
                    sparseArr[loop][1]=j;
                    sparseArr[loop][2]=chessArr1[i][j];

                }
            }
        }

        2.4.显示稀疏数组
        方式1

for (int i = 0; i < loop+1; i++) {
            for (int j = 0; j < 3; j++) {
                System.out.printf("%d\t",sparseArr[i][j]);
            }
            System.out.println();
        }

       方式2

for (int i = 0; i < sparseArr.length; i++) {
            System.out.println(sparseArr[i][0]+"\t"+sparseArr[i][1]+"\t"+sparseArr[i][2]);
        }

   运行效果:

3.稀疏数组 ——>二维数组

        3.1先遍历稀疏数组得到创建二维数组的信息

for (int i = 0; i < sparseArr.length; i++) {
            System.out.println(sparseArr[i][0]+"\t"+sparseArr[i][1]+"\t"+sparseArr[i][2]);
        }

运行效果:



        从稀疏数组的第一行信息中我们看出,它所代表的是一个11行1列有两个非0数据的二维数组。
        3.2创建二维数组
        由于默认初始化,因此不给二维数组遍历赋值,它里面的所有元素默认初始化为0

int[][] td =new int[sparseArr[0][0]][sparseArr[0][1]];

        3.3给二维数组赋值

        3.3.1从稀疏数组的第二行开始,根据规则把非0数据赋给二维数组。这里,两个数组的对应关系显得尤为重要。
        3.3.2因为要赋值数据的个数是稀疏数组行数-1,所以我们用稀疏数组行数作为循环条件。
        3.3.3规律:二维数组中要赋值的位置:行数:稀疏数组第1列;列数:稀疏数组第2列;值:稀疏数组第3列
        3.3.4for循环中,i从1开始,因为第1行不存放具体数据信息【下标从0开始】;i<sparseArr.length;sparse.length为n,说明非0数据的个数为i-1,数组下标从0开始,那么第n个非0数据的信息正好在稀疏数组中下标为n的数据上。最后一个数据的下标为spare.length-1,设置循环条件为i<sparseArr.length,当i=sparseArr.length时跳出循环。

for (int i = 1; i < sparseArr.length; i++) {
            td[sparseArr[i][0]][sparseArr[i][1]]=sparseArr[i][2];
        }

        3.4至此,稀疏数组转化二维数组完成,打印一下输出二维数组内容。

for (int i = 0; i < td.length; i++) {
            for (int j = 0; j < td[0].length; j++) {
                System.out.printf("%d\t",td[i][j]);
            }
            System.out.println();
        }

        显示效果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值