对称矩阵的压缩存储

xiaoxiao2021-02-28  79

矩阵对于学数学的都不陌生,说白了就是一个二维数组嘛,不过矩阵里有一些很有特色的矩阵,今天我们就来看一种——对称矩阵。

下面来看一个对称矩阵,顺便分析一下,对称矩阵的性质,以便我们随后的研究。

我们看,中间红线标出的就是对称线,既然是对称,那么首先这个矩阵得是方阵,也就是说,行数和列数相等;整个矩阵分为两部分,上三角和下三角,在上三角行号小于列号,而在下三角行号大于列号;最后就是对称表现出来的性质了:a[i][j]=a[j][i]。

那么总结一下,对称矩阵:设一个N*N的矩阵A,A中任意元素A[i][j],当且A[i][j]==A[j][i](0 <= i <= N-1 && 0 <=j <= N-1),则矩阵A是对称矩阵。

了解了对称矩阵,我们发现,对称矩阵里的数据有雷同的,那么我们就要想,要是将这些重复的数据去掉的话,是不是可以节省一大波空间呢?

这就是对称矩阵的压缩存储了,知道了对称矩阵的性质之后,我们再存储的时候,只需将下三角或上三角加上对角线存储就可以了。

不过压缩后的矩阵和原矩阵有一个重要的对应关系:

下三角存储i>=j,SymmetricMatrix[i][j] == Array[i*(i+1)/2+j]

那么接下来就来实践一下吧。

#include<iostream> using namespace std; template<class T> class SymmetricMatrix { public: //存储矩阵的下三角:a[i][j]=_array[i*(i+1)/2+j] //1+2+3+……+n=n*(n+1)/2 SymmetricMatrix(T(*a)[5])//一维数组指针 : N(5) { _array = new T[N*(N + 1) / 2]; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { _array[i*(i + 1) / 2 + j] = a[i][j]; } } } T& Acess(int row, int col) { if (row < col)//如果是上三角,那么直接将行列数字交换即可 { swap(row, col); } return _array[row*(row + 1) / 2 + col]; } //下三角:row>col const T& Acess(int row, int col)const { if (row < col)//如果是上三角,那么直接将行列数字交换即可 { swap(row, col); } return _array[row*(row + 1) / 2 + col]; } ~SymmetricMatrix() { if (_array) { delete [] _array; //new/delete 匹配使用 _array = NULL; } } void PrintMatrix() { for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { if (i < j) cout << _array[j*(j + 1) / 2 + i]<<" "; else //else 必须有,否则会多执行下面的语句 cout << _array[i*(i + 1) / 2 + j]<<" "; } cout << endl; } } private: T* _array; size_t N; }; void FunTest() { int a[5][5] = { { 0, 1, 2, 3, 4 }, { 1, 0, 1, 2, 3 }, { 2, 1, 0, 1, 2 }, { 3, 2, 1, 0, 1 }, { 4, 3, 2, 1, 0 } }; SymmetricMatrix<int> sm(a); int ret = sm.Acess(2, 3); cout << ret << endl; sm.PrintMatrix(); } int main() { FunTest(); return 0; }
转载请注明原文地址: https://www.6miu.com/read-33643.html

最新回复(0)