luoshen7

导航

稀疏数组与二维数组之间的转换

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

数据图展示:


完整代码:

package datas;

/**
 * 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();
        }

    }
}

代码分析:
创建二维数组信息:

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数据的个数。创建稀疏数组。
1.1这里使用了增强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.1稀疏数组的列数为三列是固定的。行数为非0数据的个数+1,因为第一行存放二维数组整体信息,其他每行对应非0数据的具体信息
2.2稀疏数组第一行整体信息具体为: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;

3.我们已经知道了二维数组非0数据的个数,现在我们要遍历二维数组找到非0数据的具体行列数信息存入稀疏数组。
3.1当第一个非0数据出现时,我们当然知道将信息保存在稀疏数组的第二行,但是在循环中,第二个、第三个、...数据出现时呢?这样操作只会不断更新稀疏数组第二行的数据,但之前非0数据的信息并未保存下来。因此,我们不能将数据存放的位置写死,要找出非0数据的位置信息与稀疏数组的位置信息的规律,将二者联系起来。
3.2当第一个非0数据出现时,我们将信息存放在稀疏数组的第二行,当第二个非0数据出现时,我们将信息存放在稀疏数组的第三行,以此类推...我们找出的规律是:将第n个出现的数据保存在稀疏数组的第n+1行
3.3我们要创建一个变量显示这是第几个非0数据,并且这个变量+1后也将成为稀疏数组的行数。
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];

                }
            }
        }

4.显示稀疏数组
4.1方式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();
        }

4.2方式2

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

5.将稀疏数组使用IO流知识保存在文件中,这个我还不会,二次更新是填坑补充这部分知识。

稀疏数组 ————> 二维数组
1.将文件中的信息使用IO流知识转化成稀疏数组,这个我还不会,二次更新是填坑补充这部分知识。
2.先遍历稀疏数组得到创建二维数组的信息

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

显示效果:

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

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

4.从稀疏数组的第二行开始,根据规则把非0数据赋给二维数组。这里,两个数组的对应关系显得尤为重要。
4.1因为要赋值数据的个数是稀疏数组行数-1,所以我们用稀疏数组行数作为循环条件。
4.2规律:二维数组中要赋值的位置:行数:稀疏数组第1列;列数:稀疏数组第2列;值:稀疏数组第3列
4.3for循环中,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];
        }

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

        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();
        }

posted on 2024-03-15 10:47  洛神的杂货铺  阅读(31)  评论(0)    收藏  举报