【C++】矩阵的压缩存储,还原,转置

矩阵的格式相当于是一个二维数组,如下图

上图就是一个特殊的矩阵,对称矩阵

一、对称矩阵

对称矩阵中的元素有一定的规律,就是行下标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);
	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值