数组之特殊矩阵的压缩储存

数组是大家已经很熟悉的一种数据类型,几乎所有的程序设计语言都把数组类型定为固有类型,在这我就不再介绍数组的基础知识(如:定义等知识)了。下面我们直接看矩阵的储存,一般情况下,矩阵使用二维数组储存的,但是,对于数据量非常大的矩阵,这样储存就显得乏力了,又浪费空间资源,下面我们就看看有没有更好的储存方法呢。很明显,我们可以用一位数组压缩储存有些矩阵,下面就来研究几个特殊矩阵吧。

(1)对称矩阵

若n阶矩阵A中的元素满足下述性质:aij=aji   0<=i,j<=n-1则称为n阶对称矩阵。

很明显,我们只用为每一对对称元素分配一个储存空间,则可将n2个元素压缩储存到n(n+1)/2个元的空间中。

假设以一维数组a[n(n+1)/2]作为n阶对称矩阵的储存结构,则a[k]与矩阵元素之间存在着一一对应的关系:当i>=j时,k=i*(i+1)/2+j;当i<j时,k=j*(j+1)+i;

代码如下:

 1 #include<iostream>
 2 #include<iomanip>
 3 using namespace std;
 4 int main()
 5 {
 6     while(1)
 7     {
 8         int n,a[1000];
 9     cin>>n;
10     cout<<"请输入"<<n*(n+1)/2<<"个数:";
11     for(int i=0;i<n*(n+1)/2;i++)
12         cin>>a[i];
13     for(int i=0;i<n;i++)
14     {
15         for(int j=0;j<n;j++)
16         {
17             if(i>=j)
18                 cout<<setw(3)<<a[i*(i+1)/2+j]<<" ";
19             else
20                 cout<<setw(3)<<a[j*(j+1)/2+i]<<" ";
21         }
22         cout<<endl;
23     }
24     cout<<"节约"<<n*n-n*(n+1)/2<<"个空间."<<endl;
25     }
26 
27     return 0;
28 }

(2)上、下三角矩阵

所谓上、下三件矩阵是指矩阵上(下)三角(不包括对角线)中的元素均为常数c或0的n阶矩阵。则除了和对称矩阵一样,只储存其下(上)三角中的元素之外,再加一个储存常数c的储存空间即可。

示例代码如下:

#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
    while(1)
    {
        int n,a[1000];
        cin>>n;
        cout<<"请输入"<<n*(n+1)/2+1<<"个数:";
        for(int i=0;i<n*(n+1)/2+1;i++)
            cin>>a[i];
     //上三角
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            if(i<=j)
                cout<<setw(3)<<a[(2*n-i+1)*i/2+(j-i)]<<" ";
            else
                cout<<setw(3)<<a[n*(n+1)/2]<<" ";
        }
        cout<<endl;
    }
    cout<<"节约"<<n*n-n*(n+1)/2-1<<"个空间."<<endl;
    }
    //下三角
     /*for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            if(i>=j)
                cout<<setw(3)<<a[i*(i+1)/2+j]<<" ";
            else
                cout<<setw(3)<<a[n*(n+1)/2]<<" ";
        }
        cout<<endl;
    }*/
    return 0;
}

(3)对角矩阵(带状矩阵)

对角矩阵是指所有的非0元素都集中在以主对角线为中心的袋装区域中,即除了主对角线上和直接在对角线上、下方若干条对角线上的元素之外,所有其他的元素皆为0。对角矩阵

假设对角矩阵的半宽为d,则对于n阶矩阵需要n*(2*d+1)-d*d-d+1个储存空间,原理与上面的几乎一样,就不重复了,下面看实现代码吧

#include<iostream>
#include<cmath>
#include<iomanip>
using namespace std;
int main()
{
    int n,d,a[100],m;
    cin>>n>>d;
    cout<<"请输入"<<(n*(2*d+1)-d*d-d+1)<<"个数:";
    for(int i=0;i<n*(2*d+1)-d*d-d+1;i++)
        cin>>a[i];
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            if(fabs(i-j)<=d)
                cout<<setw(3)<<a[(i*(2*d+1)-d)+(j-i+d)]<<" ";
            else
                cout<<setw(3)<<a[n*(2*d+1)-d*d-d]<<" ";
        }
        cout<<endl;
    }
    cout<<"节约"<<n*n-(n*(2*d+1)-d*d-d+1)<<"个空间."<<endl;
    return 0;
}

上面是比较简单的矩阵压缩储存,更复杂的待续。。。。

原文地址:https://www.cnblogs.com/czx1/p/4932698.html