稀疏矩阵
在矩阵中,若数值为0的元素数目远远多于非0元素的数目,并且非0元素分布没有规律时,则称该矩阵为稀疏矩阵;与之相反,若非0元素数目占大多数时,则称该矩阵为稠密矩阵。定义非零元素的总数比上矩阵所有元素的总数为矩阵的稠密度。
此处使用JAVA代码实现对矩阵的压缩与扩展
可以想象,当我们玩五子棋或其他棋类游戏时,当我们需要对游戏来进行存档。那么可以把棋盘来当作一个矩阵,有棋子的地方用相应的数字来进行表示。没有棋子的地方用0来表示。
这里假设棋盘为11*11的一个矩阵。
倘若棋盘中1为黑子,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 1 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 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 0 0 0 0 0 0 0
那么问题来了,我们要存储这盘棋。那我们需要将这盘棋所有的二维数组整个存储吗?当然不是,我们可以考虑将原始矩阵的行和列存储进来,并将对应行列的值进行存储下来,这样就只需要存储较少的数值了。如下图:
row | col | value |
---|---|---|
11 | 11 | 2 |
2 | 2 | 1 |
2 | 3 | 2 |
其中,第一行为原始矩阵的行和列,第一行的value为一共有多少个棋子(即有多少个有意义的值)。第二行往后为对应值的存储的行和列在哪个地方。
所以我们可以利用这种思想,将原始矩阵压缩,在通过IO流存储到本地文件,需要使用时,再将矩阵恢复为原始矩阵即可:
JAVA代码实现稀疏矩阵
class ReducedDimensionMatrix {
public static void main(String[] args) {
//原始矩阵--------------------
int aa[][] = new int[11][11];
aa[2][2] = 1;
aa[2][3] =2;
int sum =0; //用来记录有多少不为0的数据
System.out.println("原始矩阵为:");
for(int[] i : aa) {
for(int j : i) {
if(j!=0){
sum++;
}
System.out.print(j+" ");
}
System.out.println();
}
//稀疏矩阵--------------------------
int bb[][] = new int[sum+1][3];
bb[0][0] = 11; //记录总行数
bb[0][1] = 11; //记录总列数
bb[0][2] = sum;
int n=1;
for(int i =0 ; i<aa.length; i++) {
for(int j=0;j<aa[i].length;j++){
if(aa[i][j]!=0){
bb[n][0]=i;
bb[n][1] = j;
bb[n][2] = aa[i][j];
n++;
}
}
}
System.out.println("得到的稀疏矩阵为:");
for(int [] i : bb){
for(int j : i){
System.out.print(j+" ");
}
System.out.println();
}
//恢复稀疏矩阵-----------------------
int cc[][] = new int[bb[0][0]][bb[0][1]];
for(int i=1;i<bb.length;i++){
for(int j=0;j<bb[i].length;j++){
cc[bb[i][0]][bb[i][1]] = bb[i][2];
}
}
System.out.println("恢复得的矩阵为:");
for(int [] i : cc){
for(int j : i){
System.out.print(j+" ");
}
System.out.println();
}
}
}