其他分享
首页 > 其他分享> > 稀疏数组

稀疏数组

作者:互联网

假设现在有一个如下的八行八列的二维数组:

0 0 0 0 0 0 0 0
0 0 1 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 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0

先使用Java实现该数组:

package com.dh.array;

public class SparseArray {

    public static void main(String[] args) {
        //定义原始数组
        int[][] oldArr = new int[8][8];
        oldArr[1][2] = 1;
        oldArr[2][3] = 2;
        //打印原始数组
        for (int[] ints : oldArr) {
            for (int anInt : ints) {
                System.out.print(anInt+"\t");
            }
            System.out.println();
        }
    }
}

我们可以看到,只有一个1,一个2,剩下的都是0,那我们能不能直接记录下1和2的位置,然后记录下剩下的都是0来缩小规模呢?

答案是可以的,我们可以使用稀疏数组来存储这类数据。

数组转换为稀疏数组存储格式:

1.定义一个二维数组(行数:存储数据+1,列数:3);

2.第一行存储的数据为:原始数组的行数,原始数组的列数,储存的值的个数;

3.每一行存储一个数据:数据的行数,数据的列数,值

以上述例子分析:

第一行数据:8,8,2		//八行,八列,存储两个值(1和2)
第二行数据:1,2,1		//第二行第三列的1(第二行下标为1,第三列下标为2,所以为1,2)
第三行数据:2,3,2		//第三行第四列的2

如何使用Java代码实现呢?

第一行的数据很简单

行数:二维数组.length;

列数:二维数组[0].length;

个数:遍历使用一个计数器计数即可。

首先要获取有效值的个数:

 //首先要确定存储数据的个数用以确定稀疏数组的行数(个数+1)
int count = 0;
for (int i = 0; i < oldArr.length; i++) {
    for (int j = 0; j < oldArr[i].length; j++) {
        if(oldArr[i][j] != 0){
            count++;
        }
    }
}

然后可以确定稀疏数组的行数(有效值的个数+1),列数固定为3,就可以声明一个稀疏数组并且分配空间了:

//声明稀疏数组并且分配空间 
int[][] newArr = new int[count+1][3];

第一行的数据也可以确定了:

//确定稀疏数组的第一行数据
newArr[0][0] = oldArr.length;
newArr[0][1] = oldArr[0].length;
newArr[0][2] = count;

接着遍历原始数组,取得要存储的值,并且获取该值所在的行数和列数:

//确定第二行之后的数据
int num = 1;    //用以确认行数,从第二行开始,下标为1
for (int i = 0; i < oldArr.length; i++) {
    for (int j = 0; j < oldArr[i].length; j++) {
        if(oldArr[i][j] != 0){	//要储存的值的条件
            newArr[num][0] = i; //存储值所在的行数
            newArr[num][1] = j; //存储值所在的列数
            newArr[num][2] = oldArr[i][j]; //存储的值
            num++;  //记录完一行,行数加一
        }
    }
}

最后输出,验证一下结果:

结果一致!没有问题~

那稀疏数组怎么还原为原始的数组呢?

//稀疏数组还原为原始数组
int[][] oldArr1 = new int[newArr[0][0]][newArr[0][1]];	//通过稀疏数组的第一行的前两个数确定原始数组的行数和列数
for (int i = 1; i <= newArr[0][2]; i++) {//从稀疏数组的第二行开始为原始数组的值,数据个数从稀疏数组的第一行的第三个数确定
    oldArr1[(newArr[i][0])][(newArr[i][1])] = newArr[i][2];//稀疏数组每行的第一、第二个数为原始数组的下标,第三个数为值
}
System.out.println("==========================");
System.out.println("稀疏数组还原:");
for (int[] ints : oldArr1) {
    for (int anInt : ints) {
        System.out.print(anInt+"\t");
    }
    System.out.println();
}

还原结果也是正确的~


完整代码如下:

package com.dh.array;

public class SparseArray {

    public static void main(String[] args) {
        
		//1.定义原始数组
        int[][] oldArr = new int[8][8];
        oldArr[1][2] = 1;
        oldArr[2][3] = 2;
        //打印原始数组
        System.out.println("原始数组:");
        for (int[] ints : oldArr) {
            for (int anInt : ints) {
                System.out.print(anInt+"\t");
            }
            System.out.println();
        }

        //----------------------------------------------------------------------------------
		//2.原始数组--->稀疏数组
        //首先要确定存储数据的个数用以确定稀疏数组的行数(个数+1)
        int count = 0;
        for (int i = 0; i < oldArr.length; i++) {
            for (int j = 0; j < oldArr[i].length; j++) {
                if(oldArr[i][j] != 0){
                    count++;
                }
            }
        }

        //定义一个稀疏数组
        int[][] newArr = new int[count+1][3];
        //确定第一行的数据
        newArr[0][0] = oldArr.length;
        newArr[0][1] = oldArr[0].length;
        newArr[0][2] = count;

        //确定第二行之后的数据
        int num = 1;    //用以确认行数,从第二行开始,下标为1
        for (int i = 0; i < oldArr.length; i++) {
            for (int j = 0; j < oldArr[i].length; j++) {
                if(oldArr[i][j] != 0){  //要储存的值的条件
                    newArr[num][0] = i; //存储值所在的行数
                    newArr[num][1] = j; //存储值所在的列数
                    newArr[num][2] = oldArr[i][j]; //存储的值
                    num++;  //记录完一行,行数加一
                }
            }
        }

        System.out.println("==========================");
        System.out.println("稀疏数组:");
        //遍历稀疏数组
        for (int[] ints : newArr) {
            for (int anInt : ints) {
                System.out.print(anInt+"\t");
            }
            System.out.println();
        }

        //------------------------------------------------------------------------------------
        //3.稀疏数组--->原始数组
        //通过稀疏数组的第一行的前两个数确定原始数组的行数和列数
        int[][] oldArr1 = new int[newArr[0][0]][newArr[0][1]];	
        
        //从稀疏数组的第二行开始为原始数组的值,数据个数从稀疏数组的第一行的第三个数确定
        for (int i = 1; i <= newArr[0][2]; i++) {
            //稀疏数组每行的第一、第二个数为原始数组的下标,第三个数为值
            oldArr1[(newArr[i][0])][(newArr[i][1])] = newArr[i][2];
        }
        System.out.println("==========================");
        System.out.println("稀疏数组还原:");
        for (int[] ints : oldArr1) {
            for (int anInt : ints) {
                System.out.print(anInt+"\t");
            }
            System.out.println();
        }
    }
}

换来换去的话可能会有一点点绕,在写程序的时候尽量细心一点,如果不理解,可以拿纸笔写写画画一下,就很容易明白了。

若有错误,也请指出~

标签:int,newArr,稀疏,length,数组,oldArr
来源: https://www.cnblogs.com/denghui-study/p/14287484.html