我们大家都在高中或者大学接触过矩阵了(具体是什么时候我也不知道了,忘了。。。)
那么,我简单说一下特殊的矩阵:对称矩阵;
什么是对称矩阵
对称矩阵就是:元素以对角线为对称轴对应相等的矩阵。对称矩阵。
对称矩阵在计算机中的存储
我们都知道堆成矩阵的是以对角线为分割线上三角和下三角一样的一个矩阵,所以我们知道这个对称矩阵我们只需要存储一半(上三角或者下三角)就可以了,为的就是节约内存(没办法,内存条毕竟太贵了,买不起啊 !!!)。
我们从上图可以看到,用红色三角圈起来的就是我们将要在计算机内存中存放的数据。
那么,如何将这些数据合理的存在内存中,在这我们就不用二维数组来存储了,一维数组完全能够胜任这个工作函简单。
我们以下三角为例:
从上面的全矩阵中我们可以很简单的计算出下三角元素的个数(n*(n+1)/2)简单的应用一下高斯公式。
我们还能发现出:
1、对称矩阵中我们的行和列是绝对相等的
2、在全矩阵中,上三角和下三角的关系 array[i][j] = array[j][i].
3、在下三角的存储方式下,行>=列。
我们记住这两点就能大致写出代码:
#include<iostream>
using namespace std;
template<class T>
class SymmetricMatrix //对称矩阵的压缩
{
public:
SymmetricMatrix(const T* array, size_t N)
: _row(N)
, _col(N)
{
int idx = 0;
_pData = new T[N*(N + 1) / 2]; //创建一个一维数组对矩阵的下三角进行压缩
for (int i = 0; i < N; i++)
{
for (int j = 0; j <= i; j++) //j<=i 直接就给我们呈现出的直接就是一个下三角
{
_pData[idx] = array[i*N + j];
idx++;
}
}
}
const T& Acess(int row, int col)const //对对称矩阵中的元素进行访问,
{
if (row < col) //当row<col的时候就是上三角了,我们的坐标规律就可以应用上了
{
std::swap(row, col);
}
return _pData[row*(row + 1) / 2 + col];
}
T& Acess(int row, int col) //总是成对出现的 访问函数
{
if (row < col)
{
std::swap(row, col);
}
return _pData[row*(row + 1) / 2 + col];
}
~SymmetricMatrix()
{
if (_pData)
{
delete[] _pData;
_pData = NULL;
_col = 0;
_row = 0;
}
}
template<class T>
friend ostream& operator<<(ostream& _cout, const SymmetricMatrix<T>& sm) //对矩阵的打印
{
for (int i = 0; i < sm._row; i++)
{
for (int j = 0; j < sm._col; j++)
{
cout << sm.Acess(i, j) <<" ";
}
cout << endl;
}
return _cout;
}
private:
T* _pData; //压缩时的以为数组
size_t _row; //行
size_t _col; //列
};
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((int*)a, 5); //对称矩阵的压缩
cout << sm << endl; //打印对称矩阵,检验我们是否存储的有问题
}
int main()
{
FunTest();
return 0;
}
结果:
进行比较,我们的压缩是没有问题的。