特殊矩阵(对称矩阵)的压缩存储和解压缩

参考书目:严蔚敏《数据结构》P95-96


一、背景

​ 矩阵在工程计算中经常使用,对于一些特殊矩阵,比如对称矩阵,稀疏矩阵……有时为了节省空间,可以对这类矩阵进行压缩存储。这里只讨论对称矩阵,上(下)三角矩阵和对角矩阵,掌握其他类似对称矩阵就很容易了

二、压缩原则

​ 为多个值相同的元素只分配一个存储空间,对零元素不分配空间。

三、对称矩阵的压缩

  • 性质:
    0<=i,j<=n-1(在 程序中 数组下标是从 0 开始的)

    举例:

  • 压缩:以行序为主序存储下三角(包括对角线)元素

  • 推导如下:

    ①为书上的方法

    ②自己想的一种,在压缩 对角矩阵 时会多节省一点空间

四、程序实现 4阶 对称矩阵压缩

​ 4阶矩阵压缩(后面会总结 n阶 )

#include <iostream>
using namespace std;//原始矩阵
int a[4][4]=
{{0,4,5,6}, {4,1,7,8},{5,7,2,9},{6,8,9,3}};
//压缩矩阵
int Sa1[10];
int Sa2[10];
//通过压缩矩阵复原 原矩阵
int a1[4][4] = {0}; void Printa()
{for(int i=0; i<4; i++){for(int j=0; j<4; j++)cout << a[i][j] << "\t";cout << endl;}cout << endl;
} void MatrixCompression1()//矩阵压缩 1
{for(int i=0; i<4; i++){for(int j=0; j<=i; j++){int k = i*(i+1)/2+j;Sa1[k] = a[i][j];}}
}void MatrixCompression2()//矩阵压缩 2
{for(int i=0; i<4; i++){for(int j=0; j<=i; j++){int m = i-j;int k = 4*m-m*(m-1)/2+j;Sa2[k] = a[i][j]; }}
}int main()
{cout << "原始矩阵:" << endl;Printa(); MatrixCompression1();cout << "第一种压缩方式:"; cout << "Sa1 = ";for(int i=0; i<10; i++)cout << Sa1[i] << " "; cout << endl;MatrixCompression2();    cout << "第二种压缩方式:"; cout << "Sa2 = ";for(int i=0; i<10; i++)cout << Sa2[i] << " "; return 0;}

运行结果:

五、解压缩

压缩容易,解压难,不聪明的小脑袋瓜子想了一节课,发现直接从公式出发就好了

其实都可以用暴力法穷举出来,第一种方式我优化了一下,为 O(n2);第二种方式为 O(n4),n 表示阶数

void MatrixRecovery1()//矩阵复原1
{int i=3,j,k; for(k=9; k>=0; k--){j = k-(i+1)*i/2;if(j>=0){a1[i][j] = a1[j][i] = Sa1[k]; }else{i--;j = k-(i+1)*i/2;a1[i][j]  = Sa1[k];}}}
void MatrixRecovery2()//矩阵复原2
{int i,j,k,m; for(k=0; k<10; k++){for(i=0; i<4; i++)for(j=0; j<=i; j++){m = i-j;if(k==4*m-m*(m-1)/2+j)   {a2[i][j] = a2[j][i] = Sa2[k];break;  }}}
}

六、全部代码和运行结果

![请添加图片描述](https://img-blog.csdnimg.cn/2198cf24da4b49e785ba403cd5db6abf.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5ZCb5YWu5pWF5Lq66L6e,size_20,color_FFFFFF,t_70,g_se,x_16)
#include <iostream>
#include <iostream>
using namespace std;//原始矩阵
int a[4][4]=
{{0,4,5,6}, {4,1,7,8},{5,7,2,9},{6,8,9,3}};
//压缩矩阵
int Sa1[10];
int Sa2[10];
//通过压缩矩阵  解压缩回 原矩阵
int a1[4][4] = {0};
int a2[4][4] = {0}; void PrintArray(int a[][4])
{for(int i=0; i<4; i++){for(int j=0; j<4; j++)cout << a[i][j] << "\t";cout << endl;}cout << endl;
} void MatrixCompression1()//矩阵压缩 1
{for(int i=0; i<4; i++){for(int j=0; j<=i; j++){int k = i*(i+1)/2+j;Sa1[k] = a[i][j];}}
}void MatrixCompression2()//矩阵压缩 2
{for(int i=0; i<4; i++){for(int j=0; j<=i; j++){int m = i-j;int k = 4*m-m*(m-1)/2+j;Sa2[k] = a[i][j]; }}
}void MatrixRecovery1()//矩阵复原1
{int i=3,j,k; for(k=9; k>=0; k--){j = k-(i+1)*i/2;if(j>=0){a1[i][j] = a1[j][i] = Sa1[k]; }else{i--;j = k-(i+1)*i/2;a1[i][j]  = Sa1[k];}}} void MatrixRecovery2()//矩阵复原2
{int i,j,k,m; for(k=0; k<10; k++){for(i=0; i<4; i++)for(j=0; j<=i; j++){m = i-j;if(k==4*m-m*(m-1)/2+j)   {a2[i][j] = a2[j][i] = Sa2[k];break;  }}}} int main()
{cout << "原始矩阵 a :" << endl;PrintArray(a); cout << endl;MatrixCompression1();cout << "第一种压缩方式:"; cout << "Sa1 = ";for(int i=0; i<10; i++)cout << Sa1[i] << " "; cout << endl;MatrixCompression2(); cout << "第二种压缩方式:"; cout << "Sa2 = ";for(int i=0; i<10; i++)cout << Sa2[i] << " "; cout << endl;  cout << endl;MatrixRecovery1();cout << "第一种压缩方式的解压缩 a1 :" << endl; PrintArray(a1);MatrixRecovery2();cout << "第二种压缩方式的解压缩 a2 :" << endl; PrintArray(a2); return 0;}

运行结果:

七、n阶

改改参数就好了

#include <iostream>
using namespace std;const int RECORD = 20;//阶数//原始矩阵
int a[RECORD][RECORD]={0};
//压缩矩阵
int Sa1[RECORD*(RECORD+1)/2];
int Sa2[RECORD*(RECORD+1)/2];
//通过压缩矩阵  解压缩回 原矩阵
int a1[RECORD][RECORD] = {0};
int a2[RECORD][RECORD] = {0}; void Inita()
{int cnt = 0;for(int i=0; i<RECORD; i++)for(int j=0; j<=i; j++){a[i][j] = a[j][i] = cnt;cnt++;    }
} void PrintArray(int a[][RECORD])
{for(int i=0; i<RECORD; i++){for(int j=0; j<RECORD; j++)cout << a[i][j] << "\t";cout << endl;}cout << endl;
} void MatrixCompression1()//矩阵压缩 1
{for(int i=0; i<RECORD; i++){for(int j=0; j<=i; j++){int k = i*(i+1)/2+j;Sa1[k] = a[i][j];}}
}void MatrixCompression2()//矩阵压缩 2
{for(int i=0; i<RECORD; i++){for(int j=0; j<=i; j++){int m = i-j;int k = RECORD*m-m*(m-1)/2+j;Sa2[k] = a[i][j]; }}
}void MatrixRecovery1()//矩阵复原1
{int i=RECORD-1,j,k; for(k=RECORD*(RECORD+1)/2-1; k>=0; k--){j = k-(i+1)*i/2;if(j>=0){a1[i][j] = a1[j][i] = Sa1[k]; }else{i--;j = k-(i+1)*i/2;a1[i][j]  = Sa1[k];}}} void MatrixRecovery2()//矩阵复原2
{int i,j,k,m; for(k=0; k<RECORD*(RECORD+1)/2; k++){for(i=0; i<RECORD; i++)for(j=0; j<=i; j++){m = i-j;if(k==RECORD*m-m*(m-1)/2+j)   {a2[i][j] = a2[j][i] = Sa2[k];break;  }}}} int main()
{//初始化 原始矩阵 aInita();cout << "原始矩阵 a" << "(" << RECORD << "阶)" <<":" << endl;PrintArray(a); cout << endl;MatrixCompression1();cout << "第一种压缩方式:"; cout << "Sa1 = ";for(int i=0; i<RECORD*(RECORD+1)/2; i++)cout << Sa1[i] << " "; cout << endl;MatrixCompression2();    cout << "第二种压缩方式:"; cout << "Sa2 = ";for(int i=0; i<RECORD*(RECORD+1)/2; i++)cout << Sa2[i] << " "; cout << endl;    cout << endl;MatrixRecovery1();cout << "第一种压缩方式的解压缩 a1 :" << endl; PrintArray(a1);MatrixRecovery2();cout << "第二种压缩方式的解压缩 a2 :" << endl; PrintArray(a2); return 0;}

各阶数所花时间:



阶数 5 10 15 20 25
时间/s(编译器粗略估计的) 0.183 0.332 0.510 0.842 1.038

阶数越高,运行成本越高。

特殊矩阵(对称矩阵)的压缩存储和解压缩相关推荐

  1. linux 解压tar.jz,linux系统压缩文件和解压缩命令

    linux系统压缩文件和解压缩命令 tar命令 解包:tar zxvf FileName.tar 打包:tar czvf FileName.tar DirName gz命令 解压1:gunzip Fi ...

  2. 如何在Windows 10上压缩(和解压缩)文件

    The ZIP file format reduces the size of files by compressing them, saving disk space, and reducing n ...

  3. node实现压缩文件和解压缩文件

    node.js的压缩和解压缩类库 compressing 支持格式: tar.gzip.tgz.zip 以zip为例,tar,tgz和gzip与zip相同. 压缩单个文件: const compres ...

  4. 35、矩阵(稀疏矩阵)的压缩存储(一)

    为了节省存储空间并且加快处理速度,需要对这类矩阵进行压缩存储,压缩存储的原则是:不重复存储相同元素:不存储零值元素. 一.相关概念 ㈠特殊矩阵:矩阵中存在大多数值相同的元,或非0元,且在矩阵中的分布有 ...

  5. 使用Opencv对图像进行压缩和解压缩

    内容 1.关于压缩的必要性 2.API介绍 2.1 imencode() 2.2 imdecode() 3.接口介绍 1.关于压缩的必要性   最近在一个项目中需要将工业相机采集到的图像通过jsonr ...

  6. Java基础19:IO流—缓冲流、转换流、序列化、打印流、压缩流和解压流

    IO流中的一些其他流:缓冲流.转换流.序列化.打印流.压缩流和解压流 1. 缓冲流 IO流除了一些基本的流,还有在此基础上发展出来的一些更强大的流.比如能够高效读写的缓冲流,能够转换编码的转换流,能够 ...

  7. sql server压缩_SQL Server 2016中的压缩和解压缩功能

    sql server压缩 The concept of data compression is not a new on for SQL Server Database Administrators ...

  8. LZ77算法压缩和解压缩

    LZ77简介 Ziv和Lempel于1977年发表题为"顺序数据压缩的一个通用算法(A Universal Algorithm for Sequential Data Compression ...

  9. Linux常用命令——压缩和解压缩命令

    之前说过,在Linux系统下,文件是不区分扩展名的.但是Linux系统支持很多种压缩格式,如果压缩文件不写上扩展名,你自己创建的压缩文件可能你自己知道,但是过一阵你可能也忘记了.其他管理员也很难知道该 ...

最新文章

  1. poj2305-Basic remains(进制转换 + 大整数取模)
  2. TSM12M触摸芯片注意事项
  3. php+mssql 分页,一个PHP+MSSQL分页的例子
  4. vivo X21低调奢华 彭于晏携手黑金版来袭
  5. 深度学习笔记 第四门课 卷积神经网络 第二周 深度卷积网络:实例探究
  6. php解析doc试卷,PHP试题(卷)带答案解析.doc
  7. 一个经典实例理解继承与多态原理与优点(附源码)---面向对象继承和多态性理解得不够深刻的同学请进...
  8. java完全数判断_java基础之完数判断
  9. mybatis 自动生成integer_通过mybatis-generator-core工具自动关联表生成对应model、mappers及dao层代码类完整教程...
  10. RFC1323 timestamp PAWS的实现陷阱
  11. 第六次 Scrum Meeting
  12. 白话容器namespace
  13. Excle 常用函数
  14. 性能测试--jmeter中的用户自定义变量【13】
  15. java多线程与并发之java并发编程实践
  16. Scratch之自动走迷宫
  17. 解决ppt复制到Word的图片导出PDF后出现黑线问题,word转PDF图片不清晰的问题,ppt转矢量图问题
  18. 《从前慢》 ----- 作者:木心
  19. 在Ubuntu中使用WinUSB创建Windows启动盘
  20. Vue项目中操作svg文件

热门文章

  1. 存储中所说的蓝光和磁带库
  2. 使用LaTeX写数学公式
  3. 囚徒困境(进化优化算法)
  4. vb.net 图片水平翻转_犁耕作业效果差?试试大马力拖拉机液压翻转犁正确调整与使用方法...
  5. 前端做微信好友分享_前端-微信分享
  6. 微信公众号如何添加文档附件【教程】
  7. 01改变世界:机械之美——机械时期的计算设备
  8. Windows8 照片查看器,图片发黄解决方法~
  9. 计算机CPU工作(多核/缓存)原理
  10. 怎么搜索一下整个网络的计算机,如何快速查找自己电脑IP地址?