基本原理:
若将对称矩阵中的每个元素都保存起来,占用的空间会随着矩阵为数的增多而增多。
根据对称矩阵的性质,我们可以在存储时只存储矩阵的上三角或下三角,最多存储N*(N+1)/2个数据,在数据较多的情况下,会节省很多的空间。也就是说,压缩存储称矩阵存储时只需要存储上三角/下三角的数据,所以最多存储n(n+1)/2个数据(相当于1+2+…+n,即等差数列求和)。
源码如下:
#include<stdio.h>
#include<iostream>
using namespace std;
template<class T>
class CompressionMatrix
{
public:
CompressionMatrix(T* arr,int sz)
:_data(new T[sz*(sz+1)/2])
,_size(sz)
{
int index=0;
//压缩储存过程
for(int i=0;i<sz;++i)
{
for(int j=0;j<sz;++j)
{
if (i>=j)//_data中储存下三角的数据
{
_data[index]=arr[i*sz+j];
index++;
}
else
break;
}
}
}
//获取某个坐标的数据,i和j代表该数据在矩阵中的横纵坐标
T GetDate(int i,int j)
{
if (i>=j)//下三角数据
{
return _data[i*(i+1)/2+j];
}
else//上三角数据
{
std::swap(i,j);//将横坐标和从坐标值交换;
return _data[i*(i+1)/2+j];
}
}
//打印矩阵的数据
void PrintfMatrix()
{
for (int i=0;i<_size;++i)
{
for (int j=0;j<_size;++j)
{
cout<<GetDate(i,j)<<" ";
}
cout<<endl;
}
}
~CompressionMatrix()
{
if (_data!=NULL)
{
delete[] _data;
_data=NULL;
_size=0;
}
}
protected:
T* _data;//储存数据的数组
int _size;//储存原始对称矩阵的行数(或列数)
};
int main()
{
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},
};
/*int a[10][10]=
{
{0,1,2,3,4,5,6,7,8,9},
{1,0,1,2,3,4,5,6,7,8},
{2,1,0,1,2,3,4,5,6,7},
{3,2,1,0,1,2,3,4,5,6},
{4,3,2,1,0,1,2,3,4,5},
{5,4,3,2,1,0,1,2,3,4},
{6,5,4,3,2,1,0,1,2,3},
{7,6,5,4,3,2,1,0,1,2},
{8,7,6,5,4,3,2,1,0,1},
{9,8,7,6,5,4,3,2,1,0},
};*/
CompressionMatrix<int> cm((int*)a,5);//将二维数组强制转换为一维数组指针,是问题更简单,5改为10即可
cm.PrintfMatrix();
return 0;
}
修改后: