package com.data_struct.map;
//两个版本,一个用于所有对称矩阵的压缩,一个用于无向图的矩阵压缩
public class Symmetric_matrix_compress
{
public static void main(String[] args)
{
//测试:matrix为对称矩阵
int[][] matrix ={{0, 1, 1, 1, 0, 0},
{1, 0, 0, 0, 1, 1},
{1, 0, 0, 0, 1, 0},
{1, 0, 0, 0, 0, 1},
{0, 1, 1, 0, 0, 0},
{0, 1, 0, 1, 0, 0}};
symmetricMatrixCompress a = new symmetricMatrixCompress();
decompression b=new decompression();
int[] compress;//压缩数组
compress = a.compress01(matrix);
System.out.println("压缩后:");
for (int i = 0; i < 21; i++)
{
System.out.print(compress[i] + ",");
}
System.out.println();
System.out.println("解压后:");
matrix=b.decompression01(compress);
for (int i = 0; i < 6; i++)
{
for (int j = 0; j < 6; j++)
{
System.out.print(matrix[i][j]+",");
}
System.out.println();
}
}
}
class symmetricMatrixCompress
{
//通用对称矩阵压缩,记录对角线和上半部分。
public int[] compress01(int[][] matrix)
{
/*第一步,我想先得到压缩后数组的长度。
举例:
0 1 1 0
1 0 0 0
1 0 0 0
0 0 0 0
我们想得到压缩后的数组长度(即对角线+上三角的个数),
即
0 1 1 0
0 0 0
0 0
0
个数为4+3+2+1,即可发现一个规律每一个对称矩阵压缩后数组大小都是对称矩阵的边长加到1;
通过数学规律(首项+末项)*项数/2 即 (x+1)*x/2 简化后: (x*x+x)/2
然后我们开辟一个(x*x+x)/2 的数组,用于存储对角线和上三角。
* */
int length = matrix.length;//得到对称矩阵的边长
int count = (length * length + length) / 2;//通过对称矩阵的特性得到对角线和上半部分的点的数量。
int[] compressMatrix = new int[count];//初始化一个数组,数组大小为对角线和上半部分的数量,即上一句的count。
int x = 0, y = 0;
/*老师,下面是我的核心算法:上面的x和y是对称矩阵的下标。
举例解释:
0 1 1 0
0 0 0
0 0
0
我需要循环4+3+2+1次
即10次赋值。
每当y==4 即下面的if(y==length)
马上跳转到下一排
即x++ 然后让y=x,这样又能从第二排第一个开始循环赋值。
每一排赋值都如此,直到压缩完毕。
* */
for (int i = 0; i < count; i++)
{
compressMatrix[i] = matrix[x][y];
y++;
if (y == length)
{
x++;
y = x;
}
}
return compressMatrix;
}
//专门用于无向图矩阵压缩,不记录对角线,只记录上半部分,因为无向图的对角线都是0。
public int[] compress02(int[][] matrix)
{
int length = matrix.length;
int count = (length * length - length) / 2;//通过对称矩阵的特性得到需要记录的点。
int[] compressMatrix = new int[count];//存储上半部分。
int a = 0, b = 1;
for (int i = 0; i < count; i++)
{
compressMatrix[i] = matrix[a][b];
b++;
if (b == length)
{
a++;
b = a + 1;
}
}
return compressMatrix;
}
}
class decompression
{
//通用
public int[][] decompression01(int[] matrix)
{
int width=0,count=0;
while(count!=matrix.length)
{
width+=1;
count+=width;
}
int[][] symmetricMatrix=new int[width][width];
int b=0,c=0;
for (int i = 0; i < matrix.length; i++)
{
symmetricMatrix[b][c]=matrix[i];
symmetricMatrix[c][b]=matrix[i];
c+=1;
if (c==width)
{
b+=1;
c=b;
}
}
return symmetricMatrix;
}
}
下面的是压缩函数的详细注释,解压函数就是逆向过程