稀疏数组
一、什么是稀疏数组?
1、稀疏矩阵的官方定义
在矩阵中,若数值为0的元素数目远远多于非0元素的数目,并且非0元素分布没有规律时,则称该矩阵为稀疏矩阵;与之相反,若非0元素数目占大多数时,则称该矩阵为稠密矩阵。定义非零元素的总数比上矩阵所有元素的总数为矩阵的稠密度。
2、稀疏数组
当一个数组中大部分元素为0,或者为同一值(也就是说可以不是0)的数组时,可以使用系数数组来保存该数组。
2.1、大部分怎么去理解
通常认为矩阵中非零元素的总数比上矩阵所有元素总数的值小于等于0.05时,则称该矩阵为稀疏矩阵(sparse matrix)。
3、为什么要稀疏数组
比较基本的意义是矩阵中的大多数元素为零,并且可以利用零元素节约大量存储、运算和程序运行时间。简而言之,就是压缩,以减少时间、空间等。
4.拓展稀疏矩阵用途
稀疏矩阵几乎产生于所有的大型科学工程计算领域,包括计算流体力学、统计物理、电路模拟、图像处理、纳米材料计算等。
二、稀疏数组的处理方式
1.记录数组一共有几行几列,有多少个不同的值。(这些信息,将写在后面数组中的第一行中)
2.把具有不同值的元素和行列及值,记录在一个小规模的数组中,从而缩小程序的规模。
如图:
分析:根据原数组的数据,可以得出,原数组,共有9个除0以外的有效数据,所以我们可以将缩小后的数组的第一行记录在这里面。原数组有6行7列,并且只有9个有效值,所以我们缩小后的数组的第一行可以是6 —7— 9。
因为原数组有9个有效值,所以我们可以定义九行来分别记录这9个数。比如:原数组中的有效值1,在第一行第四列,用数组表示的话就是0行3列。此时,我们就可以把它记录在缩小后的数组中,记为:0—3—1。后面的有效值,以此类推。行,列,有效值的记录,其实就是找原数组的有效值的横坐标、纵坐标。
三、实现稀疏数组转换代码
//稀疏数组
public class ArrayDemo08 {
public static void main(String[] args) {
//创建一个二维数组 11*11 0:没有棋子 1:黑旗 2:白旗
int[][] array1 = new int[11][11]; //11*11的格子出来了
array1[1][2] = 1;
array1[2][3] = 2;
//输出原始数组
System.out.println("输出原始数组:");
for (int[] ints:array1) {
for (int anInt: ints) {
System.out.print(anInt+"\t");
}
System.out.println();
}
System.out.println("--------------------------------------------");
//转为稀疏数组
//获取有效值的个数
int sum = 0;
for (int i = 0; i < 11; i++) {
for (int j = 0; j < 11; j++) {
if (array1[i][j]!=0){
sum++;
}
}
}
System.out.println("有效值的个数为:"+sum);
//2.创建一个稀疏数组的数组
int[][] array2 = new int[sum+1][3]; //行:sum+1,因为稀疏数组的行数等于有效值的个数加上一个记录之前数组行列情况的一行;
// 列:3,就是记录行列值这三列
array2[0][0] = 11; //第一行就是存数组有几行几列几个有效值的,所以这样写
array2[0][1] = 11;
array2[0][2] = sum;
//遍历二维数组,将非零的值,存放稀疏数组中
int count = 0;
for (int i = 0; i < array1.length; i++) {
for (int j = 0; j < array1[i].length; j++) {
if (array1[i][j]!=0){ //不等于0,则为有效值
count++; //第几个有效值就存放在第几行
array2[count][0] = i; //在第count行的第一列存放横坐标
array2[count][1] = j; //在第count行的第二列存放纵坐标
array2[count][2] = array1[i][j]; //在第count行的第三列存放有效值
}
}
}
//输出稀疏数组
System.out.println("稀疏数组");
for (int i = 0; i < array2.length; i++) {
System.out.println(array2[i][0]+"\t"+array2[i][1]+"\t"+array2[i][2]);
}
System.out.println("-------------------------------------------------");
到这里实现了输出稀疏数组。
运行结果如图:
四、还原稀疏数组
/*
还原稀疏数组
*/
System.out.println("还原稀疏数组");
//1.读取稀疏数组
int[][] array3 = new int[array2[0][0]][array2[0][1]]; //因为稀疏数组的第一行的一、二列分别记录的是原数组的行数和列数
//2.给其中的元素还原它的值
for (int i = 1; i< array2.length; i++) { //不能从0开始,因为array2[0][0]==11,array3[11][11]已经越界
array3[array2[i][0]][array2[i][1]] = array2[i][2];
}
//3.打印
for (int[] ints:array3) {
for (int anInt: ints) {
System.out.print(anInt+"\t");
}
System.out.println();
运行结果如图:
五、总结
稀疏数组不难理解,平时多多练习便能掌握。我们还要掌握foreach的使用,这对数组的输出有着很便利的操作。输出稀疏数组,这并不是真正的本意,你会输出来了,这也不意味着,有多优秀,做这个程序是要让我们对数组要有个充分的理解和掌握,因为数组可能很有用,并且其中的逻辑也很有用。掌握其中的思想,理清代码的逻辑,这才是真正的程序员该去意会的。
最后,送给在代码行业上的每个人一句话,即使再小的帆也能远航!