特殊矩阵指:矩阵中有许多值相同的元素(包括0),且这些元素的分布有一定规律。当矩阵的维数比较大时,矩阵占据的内存单元相当多,这时,利用特殊矩阵数据元素的分布规律压缩矩阵的存储空间,对许多应用问题来说有重要是意义。
特殊矩阵压缩存储的方法有两种:(1)只存储相同矩阵元素的一个副本;(2)采用不等长的二维数组。
方法(1),比如对于n阶对称矩阵,行数和列数都为n,元素以主对角线为中线对称,aij=aji。那么我们可以只用一个一位数组来存储所有对称的两个值相同矩阵元素中的一个,这样n^2个元素的存储变成了n(n+1)/2个元素的存储。一维数组中元素下标k可由二维中的i和j映射为:k=i(i-1)/2+j-1(i>=j)和k=j(j-1)/2+i-1(i<j)(1<=i,j<=n)。
方法(2),就是用二维数组但每一行元素的长度不相等,对于n阶对称矩阵就是对称重复的元素只存储一次,二维数组存完后看起来就像是下三角(上三角)形状。
用代码实现n阶对称矩阵的存储,采用方法一,先建立矩阵类:
package ArrayVectorSetMatrix;
/**
* @author sun
* 创建时间:2017年4月15日上午11:16:34
*/
//设计出n阶对称矩阵,采用只存储相同矩阵元素的一个副本的压缩存储方法。
public class SynmeMatrix {
double[] a;//矩阵元素
int n;//阶数
int m;//一维数组个数
SynmeMatrix(int n){
m = n*(n+1)/2;
a = new double[m];
this.n = n;
}
public void evaluateMatrix(double[][] b){//矩阵赋值
int k = 0;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(i>=j)
a[k++] = b[i][j];//只保存下三角,按行
}
public void evaluateMatrix(double[] b){//矩阵赋值
for(int k=0;k<m;k++){
a[k] = b[k];
}
}
public SynmeMatrix add(SynmeMatrix myB){
SynmeMatrix t = new SynmeMatrix(n);
int k;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i>=j)
k = i*(i-1)/2+j-1;
else
k = j*(j-1)/2+i-1;
t.a[k] = a[k]+myB.a[k];
}
}
return t;
}
public void print(){
int k;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i>=j)
k = i*(i-1)/2+j-1;
else
k = j*(j-1)/2+i-1;
System.out.print(" "+a[k]);
}
System.out.println();
}
}
}
接着进行测试:
package ArrayVectorSetMatrix;
/**
* @author sun
* 创建时间:2017年4月15日下午3:12:35
*/
public class TestSynmeMatrix {
public static void main(String[] args) {
SynmeMatrix matrixA = new SynmeMatrix(3);
SynmeMatrix matrixB = new SynmeMatrix(3);
SynmeMatrix matrixC;
double[][] a = {{1,0,0},{2,3,0},{4,5,6}};
double[] b = {1,2,3,4,5,6};
matrixA.evaluateMatrix(a);
matrixB.evaluateMatrix(b);
System.out.println("matrixA矩阵为:");
matrixA.print();
System.out.println("matrixB矩阵为:");
matrixB.print();
matrixC = matrixA.add(matrixB);//矩阵加
System.out.println("matrixC矩阵为:");
matrixC.print();
}
}
/*
matrixA矩阵为:
1.0 2.0 4.0
2.0 3.0 5.0
4.0 5.0 6.0
matrixB矩阵为:
1.0 2.0 4.0
2.0 3.0 5.0
4.0 5.0 6.0
matrixC矩阵为:
2.0 4.0 8.0
4.0 6.0 10.0
8.0 10.0 12.0
*/