对称矩阵的压缩存储

对称矩阵的压缩存储

什么是对称矩阵的压缩存储?
就是只存上三角或者只存下三角,以下代码以下三角存储为例;

怎么做到压缩存储呢? 只存下三角呢?

其实这很简单,采用的是一维数组存储,下标访问的形式! 这样做的目的肯定在于节省空间!

在实现代码之前,我们需要搞清楚的是对称矩阵的规律;

/*下面是一个对称矩阵:

0 1 2 3
1 0 1 2
2 1 0 1
3 2 1 0

显而易见的是对称轴上都是0; 而上三角和下三角对应的数据坐标刚好是行列相反的不是吗?

比如 上三角的3(0,3),下三角的3(3,0); 同时不知道你有没有想过,我们用一维数组存储下三角时应该开辟多大的空间呢? 同样仔细观察一下也是显而易见的,除对称轴外,从第1行起,以对称轴为分界线,分别是 1个, 2个, 3个,4个数据,这就是等差数列,那么我们开辟空间也就有了依据,n*(n+1)/2;

那么我们接下来还需要考虑什么呢?
其实接下来要考虑的就是下标访问遵循的规律的问题,我们现在这里提一下,实现代码的时候我会在注释提一遍;

再来看这个

0 1 2 3
1 0 1 2
2 1 0 1
3 2 1 0

重要:坐标规律
1. 上三角和下三角对称的数据坐标严格相反;
2. 在对称轴上的数据的下标是横纵相等的,而在上三角的数据的代码的纵坐标都比横坐标大,而下三角的数据的坐标是横坐标比竖坐标大, 仔细看一下是不是这样,记住这个规律;

下面就是代码的实现;

*/

具体实现请看代码!

#include<iostream>
#include<cassert>
#include<vector>

using namespace std;

template<class T>
class SymmetricMatrix
{
public:
    SymmetricMatrix(T* arr, size_t n)
        :_matrix (new T[n*(n+1)/2])  //注意开辟空间的大小
        ,_n(n)
        ,_size(n*(n+1)/2)
    {
        //接着就是对下三角的存储了,想想前面讲的坐标规律
        int index = 0;
        for(size_t i = 0; i < _n; i++)
        {
            for(size_t j = 0; j < _n; j++)
            {
                if(i>=j)//下三角的特点,只将下三角存储;
                {
                    _matrix [index++] = arr[i*n + j ];
                }
                else
                    continue ; //小优化,节省时间;
            }
        }
    }

    //接下来就是打印了,但是在打印之前我们还需要一个函数Not(),这个函数的作用需要看了打印函数可能
    // 才比较好理解,我们先看看这个函数是怎实现的;

    T Not(size_t i, size_t j)
    {
        if(i < j)//i < j  的坐标规律代表是上三角的数据;
        {
            swap (i,j);
        }
        return _matrix [i*(i+1)/2 + j];//返回对称位置的数据;
    }

    //打印函数 --- 就是从压缩存储还原的过程;

    void  Display()
    {
        for(size_t i = 0; i < _n; i++)
        {
            for(size_t j = 0; j < _n; j++)
            {
                cout<<Not(i,j)<<" ";
            }
            cout<<endl;
        }
        cout<<endl;
    }

private:
    T* _matrix;   //压缩存储需要的一维数组
    size_t _n;    //对称矩阵的行数
    size_t _size; //一维数组中的元素个数;
};


void testSymmetricMatrix()
{
    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> s((int*)a,5);//注意我们需要的参数是一维数组指针,所以这里需要强转;

    s.Display ();
}

int main()
{
    testSymmetricMatrix();

    system("pause");
    return 0;
}
  • 8
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值