矩阵的格式相当于是一个二维数组,如下图
上图就是一个特殊的矩阵,对称矩阵
一、对称矩阵
对称矩阵中的元素有一定的规律,就是行下标row与列下标col 互换后得到的新坐标的元素与换坐标前的元素相同。
因此我们在存放对称矩阵的元素时只需将它的下三角或上三角的元素存储就可以了。
我们可以用一个类来管理这个矩阵,用容器vector来存储它的下三角的元素。(vector相当于是一个一维数组,使用时要引用头文件 #include<vector>)
(1)构造函数,将元素存入(压缩存储)
SymmetricMatrix(size_t row,size_t col,T*array)
:_row(row)
, _col(col)
{
int index = 0;
_v.resize(((1 + row)*row) >> 1); //元素总个数为 ((1+row)*row)/2
for (size_t i = 0; i < row;i++)
for (size_t j = 0; j <= i; j++) //每一行只存储到行下标与列下表相等的地方结束
_v[index++] = array[i*col + j]; //每存一个数让index向后移动
}
(2)元素访问
T& Aescc(size_t row,size_t col)
{
if (row < col)
swap(row,col);
return _v[(((row + 1)*row) >> 1)+col];
}
当行下标row小于列下标col时,表示访问的是上三角的元素,而对称矩阵中上三角中的元素与行列坐标相反的下三角中的元素相同,因此,将行坐标与列坐标互换,再取出元素就行了。
如图,当访问(2,1)时取到元素1
当访问(0,3)时,取得(3,0)处元素3
(3)打印对称矩阵
void BackSymmetricMatrix( )
{
for (size_t i = 0; i < _row; i++)
{
for (size_t j = 0; j < _col; j++)
{
cout << Aescc(i, j) << " ";
}
cout << endl;
}
}
打印时要用到两层循环,再在函数内调用访问函数Aescc()就可以了
(4)对称矩阵完整代码:
#include<iostream>
#include<vector>
#include<assert.h>
using namespace std;
#if 1
template<class T> //对称矩阵
class SymmetricMatrix
{
public:
SymmetricMatrix(size_t row,size_t col,T*array)
:_row(row)
, _col(col)
{
int index = 0;
_v.resize(((1 + row)*row) >> 1);
for (size_t i = 0; i < row;i++)
for (size_t j = 0; j <= i; j++)
_v[index++] = array[i*col + j];
}
T& Aescc(size_t row,size_t col)
{
if (row < col)
swap(row,col);
return _v[(((row + 1)*row) >> 1)+col];
}
void BackSymmetricMatrix( )
{
for (size_t i = 0; i < _row; i++)
{
for (size_t j = 0; j < _col; j++)
{
cout << Aescc(i, j) << " ";
}
cout << endl;
}
}
private:
vector<T> _v;
size_t _row;
size_t _col;
};
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 } };
SymmetricMatrix<int> sm(5,5,(int*)a);
/*int ret = sm.Aescc(2, 1);