矩阵的压缩储存(C++)

主要思想:
1.利用数学公式进行下标转换,把原本高维的数组下标转换成一维

本题以对称矩阵为例

下标转换公式如下:

在这里插入图片描述
来源是:(上一行的所有元素总和(本题中即为等差数列求和))+(这一行前面的所有元素)

注意
1.这里都是以0开头,数组中的 [0] 也要储存元素,所以公式中会出现结果为0

2.本题思想和下三角矩阵的一样,只不过是下三角矩阵要多开一个数组空间储存它上三角的值( 下三角矩阵中,上三角的值都相等),同时要更改一下 i < j 的情况。上三角矩阵就是反过来的等差数列求和.
在这里插入图片描述
3.对角矩阵,带状矩阵同理,也是找数学公式,
百度百科链接: 带状矩阵.

我采用的方法是用二维数组输入,如果想直接用一维数组接受输入也可以,注意下标就好了

#include<bits/stdc++.h>
using namespace std;
class symmetric_matrix
{
	int* ma;
	int size;
	int row_num;
public:
	symmetric_matrix()
	{
		size = 0;
		ma = new int[size];
		row_num = 0;//初始化
	}
	symmetric_matrix(int** a, int row)
	{
		int i, j;
		size = row * (row + 1) / 2;
		row_num = row;
		ma = new int[size];
		for (i = 0; i < row; i++)
		{
			for (j = 0; j < row; j++)
			{
				if (i >= j)
					ma[(i * (i + 1)) / 2 + j] = a[i][j];
				else
				{
					ma[(j * (j + 1)) / 2 + i] = a[i][j];
				}
			}
		}
	}
	void print()
	{
		int i, j;
		for (i = 0; i < row_num; i++)
		{
			for (j = 0; j < row_num; j++)
			{
				if (i >= j)
					cout << ma[(i * (i + 1)) / 2 + j] << " ";
				else
				{
					cout << ma[(j * (j + 1)) / 2 + i] << " ";
				}
				if (j == row_num - 1)
					cout << endl;
			}
		}
	}
	symmetric_matrix addmatrix(symmetric_matrix a)
	{
		symmetric_matrix b;
		b.size = size;
		b.row_num = row_num;
		delete b.ma;//释放无参构造函数开辟的空间
		b.ma = new int[size];//重新声明一个变量来储存相加后的矩阵
		int i, j;
		for (i = 0; i < size; i++)
		{

			b.ma[i] = a.ma[i] + ma[i];

		}
		return b;
	}
	symmetric_matrix submatrix(symmetric_matrix a)
	{
		symmetric_matrix b;
		b.size = size;
		b.row_num = row_num;
		delete b.ma;
		b.ma = new int[size];
		int i, j;
		for (i = 0; i < size; i++)
		{

			b.ma[i] = a.ma[i] - ma[i];

		}
		return b;
	}
//由于对称矩阵相乘不一定得到对称矩阵,所以不用考虑相乘
};
int main()
{
	int** a, b;
	cin >> b;
	int i, j;
	a = new int* [b];
	for (i = 0; i < b; i++)
	{
		a[i] = new int[b];
	}
	for (i = 0; i < b; i++)
	{
		for (j = 0; j < b; j++)
		{
			cin >> a[i][j];
		}
	}
	symmetric_matrix p(a,b);
	p.print();

	cin >> b;
	a = new int* [b];
	for (i = 0; i < b; i++)
	{
		a[i] = new int[b];
	}
	for (i = 0; i < b; i++)
	{
		for (j = 0; j < b; j++)
		{
			cin >> a[i][j];
		}
	}
	symmetric_matrix p1(a, b);



	(p.addmatrix(p1)).print();
	

	(p.submatrix(p1)).print();
	
	

}
/*1 2 3
  2 5 4
  3 4 6*/

参考:数据结构(c++版)(第二版)清华大学出版社 陈宝平等主编

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
多对角矩阵是一种特殊的稀疏矩阵,只有主对角线及其上下若干条对角线上有非零元素,其余元素均为零。因此,可以采用压缩存储方式来节省存储空间。常用的压缩存储方式有三对角矩阵、对称三对角矩阵和块对角矩阵等。 对于多对角矩阵,我们可以采用对角线压缩存储方式。具体来说,就是将矩阵中的每条对角线都保存在一个一维数组中,然后将这些数组按照对角线的位置排列起来,形成一个二维的压缩矩阵。这样,对于一个 $n\times n$ 的多对角矩阵压缩后的存储空间为 $O(n)$。 下面是一个 C++ 实现多对角矩阵压缩存储的示例代码: ```c++ #include <iostream> #include <vector> using namespace std; class DiagonalMatrix { private: vector<int> diagonal; // 对角线数组 int n; // 矩阵维度 public: DiagonalMatrix(int n) { this->n = n; diagonal.resize(2 * n - 1, 0); // 初始化对角线数组大小 } void set(int i, int j, int value) { if (i < 1 || i > n || j < 1 || j > n) { cout << "Invalid index!" << endl; return; } if (i == j) { diagonal[n - 1 + i - 1] = value; // 主对角线 } else if (i - j == 1) { diagonal[i - 2] = value; // 上一条对角线 } else if (j - i == 1) { diagonal[n + j - 2] = value; // 下一条对角线 } else { cout << "Invalid index!" << endl; return; } } int get(int i, int j) { if (i < 1 || i > n || j < 1 || j > n) { cout << "Invalid index!" << endl; return 0; } if (i == j) { return diagonal[n - 1 + i - 1]; // 主对角线 } else if (i - j == 1) { return diagonal[i - 2]; // 上一条对角线 } else if (j - i == 1) { return diagonal[n + j - 2]; // 下一条对角线 } else { return 0; } } }; int main() { DiagonalMatrix mat(5); mat.set(1, 1, 1); mat.set(2, 2, 2); mat.set(3, 3, 3); mat.set(4, 4, 4); mat.set(5, 5, 5); mat.set(1, 2, 6); mat.set(2, 3, 7); mat.set(3, 4, 8); mat.set(4, 5, 9); cout << mat.get(1, 2) << endl; // output: 6 cout << mat.get(2, 3) << endl; // output: 7 cout << mat.get(3, 2) << endl; // output: 0 (非对角线元素) return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值