一.稀疏数组的定义
稀疏数组是二维数组中的一种,是将普通数组进行压缩而得到的数组。能够压缩成稀疏数组的普通数组有以下的特点:
- 数组规模很大
- 数组中大部分的值是0或相同的值
形如:
00000000000
00100000000
00002000000
00000000000
00000000000
00000000000
00000000000
00000000000
00000000000
00000000000
00000000000
这样的数组,其中大部分是无意义的数据0,就可以通过稀疏数组的方式来进行简化。
二.稀疏数组的实现
稀疏数组是一个简化了的二维数组,由三列组成。稀疏数组的第一行记录了整个数组的基本信息,分别是原数组的行数,列数和整个数组中有意义值的个数。后面每行记录一个有意义值得具体位置信息,分别是这个值在原数组中所在的行数,列数以及这个值本身。记录值的信息的行数应与第一行第三列中有意义值的个数相同。以上面的数组为例,转化成的稀疏数组如下:
11 11 2//原数组是11*11的二维数组,其中有两个有意义的值
1 2 1//第一个有意义的值在原数组的第一行第二列,值为1
2 4 2//第二个有意义的值在原数组的第二行第四列,值为2
可以看出,稀疏数组相比原数组在规模上有了显著的简化,这种简化程度随着原数组的稀疏程度增加。因此原数组中的稀疏性越强,无意义或相同的值越多,转化成稀疏数组的简化程度就越大。一个现实中常用的实例是五子棋游戏的棋盘,可以通过稀疏数组来进行储存。
三.普通数组与稀疏数组之间的转化 代码实现
3.1 原数组化为稀疏数组
还是拿上面的数组为例,首先创建这个11*11的原数组,并赋两个有意义的值:
//创建原始二维数组(11*11)
int chessArr[][]=new int[11][11];
chessArr[1][2]=1;
chessArr[2][4]=2;//初始赋值 两个棋子
int a=0;//计数器
//输出当前数组
System.out.println("原始数组");
for(int i=0;i<11;i++){
for(int j=0;j<11;j++){
System.out.print(chessArr[i][j]);
if(chessArr[i][j]!=0){
a++;
}
}
System.out.println();
}
原始数组创建完成后,就可以进行压缩生成稀疏数组了。首先要填充的是稀疏数组的第一行,是整个原数组的基本信息。需要注意的是,稀疏数组创建时列数为3列,行数则是原数组中有意义值的个数加1,因为还要加上第一行整体数组的信息。
//生成稀疏数组,并填充第一行信息
int sparseArr[][]=new int[a+1][3];//行数为有意义的值得个数加1
sparseArr[0][0]=chessArr.length;//原数组行数
sparseArr[0][1]=chessArr[0].length;//原数组列数
sparseArr[0][2]=a;//原数组中不为0的个数
接下来要填充下面描述每个有意义值在原数组中的位置信息。从第二行开始填充,定位每个不为0的值在原数组中的位置,进行填充。
int b=1;
for(int i=0;i<chessArr.length;i++){
for(int j=0;j<chessArr[0].length;j++){
if(chessArr[i][j]!=0){
sparseArr[b][0]=i;
sparseArr[b][1]=j;
sparseArr[b][2]=chessArr[i][j];
b++;
}
}
}
这样就得到了对应的稀疏数组,输出一下检查。
//输出稀疏数组
System.out.println("稀疏数组");
for(int i=0;i<sparseArr.length;i++){
for(int j=0;j<3;j++){
System.out.print(sparseArr[i][j]);
}
System.out.println();
}
3.2 稀疏数组转回原数组
首先要通过稀疏数组的第一行建立原数组的框架,再通过后面每一行的数据来进行内容的填充。代码如下:
//转回原始数组
int chessArr2[][]=new int[sparseArr[0][0]][sparseArr[0][1]];
for(int i=1;i<=sparseArr[0][2];i++){
chessArr2[sparseArr[i][0]][sparseArr[i][1]]=sparseArr[i][2];//在原数组中进行填充还原
}
//输出当前数组
System.out.println("转换成原始数组");
for(int i=0;i<chessArr2.length;i++){
for(int j=0;j<chessArr2[0].length;j++){
System.out.print(chessArr2[i][j]);
if(chessArr2[i][j]!=0){
a++;
}
}
System.out.println();
}
3.3 完整代码
/*稀疏数组的应用:原始数组与稀疏数组之间的互相转化
*2022.1.3 */
package com.sparsearray;
public class SparseArray {
public static void main(String args[]){
//创建原始二维数组(11*11)
int chessArr[][]=new int[11][11];
chessArr[1][2]=1;
chessArr[2][4]=2;//初始赋值 两个棋子
int a=0;//计数器
//输出当前数组
System.out.println("原始数组");
for(int i=0;i<11;i++){
for(int j=0;j<11;j++){
System.out.print(chessArr[i][j]);
if(chessArr[i][j]!=0){
a++;
}
}
System.out.println();
}
//转化为稀疏数组
int sparseArr[][]=new int[a+1][3];
sparseArr[0][0]=chessArr.length;
sparseArr[0][1]=chessArr[0].length;
sparseArr[0][2]=a;
int b=1;
for(int i=0;i<chessArr.length;i++){
for(int j=0;j<chessArr[0].length;j++){
if(chessArr[i][j]!=0){
sparseArr[b][0]=i;
sparseArr[b][1]=j;
sparseArr[b][2]=chessArr[i][j];
b++;
}
}
}
//输出稀疏数组
System.out.println("稀疏数组");
for(int i=0;i<sparseArr.length;i++){
for(int j=0;j<3;j++){
System.out.print(sparseArr[i][j]);
}
System.out.println();
}
//转回原始数组
int chessArr2[][]=new int[sparseArr[0][0]][sparseArr[0][1]];
for(int i=1;i<=sparseArr[0][2];i++){
chessArr2[sparseArr[i][0]][sparseArr[i][1]]=sparseArr[i][2];
}
//输出当前数组
System.out.println("转换成原始数组");
for(int i=0;i<chessArr2.length;i++){
for(int j=0;j<chessArr2[0].length;j++){
System.out.print(chessArr2[i][j]);
if(chessArr2[i][j]!=0){
a++;
}
}
System.out.println();
}
}
}