矩阵的压缩与转置(一)
来源:互联网 发布:qt html5 混合编程 编辑:程序博客网 时间:2024/05/21 06:43
矩阵是一种应用广泛的数据,今天看书学了矩阵的转置有关算法:
矩阵的转置主要可以分为两种:普通转置 O(n*m)与 快速转置 O(m+n)
(一)普通转置
首先定义矩阵存储的结构体
单个矩阵元素存储方式定义如下:
typedef struct{int i,j;int e;}Triple;
矩阵整体定义:
typedef struct{Triple data[MAXSIZE+1];//索引下标从1开始算起int mu,nu,tu;//存储矩阵的行数、列数、非零元个数 }TSMatrix;
然后矩阵转置算法:
//稀疏矩阵的转置操作//按照矩阵M的列序进行转置 int TransposeSMatrix(TSMatrix M,TSMatrix &T){T.nu=M.mu;T.mu=M.nu;T.tu=M.tu;if(T.tu){int q=1;for(int col=1;col<=M.nu;col++)for(int p=1;p<=M.tu;p++)if(M.data[p].j==col){T.data[q].i=M.data[p].j;T.data[q].j=M.data[p].i;T.data[q].e=M.data[p].e;++q;} }return 1;}
第一种当然就没有这么完。。。在测试的时候,发现转置算法只对不含0的矩阵成功:
完整代码如下:
#include<iostream>#include<cstdlib>#include<cstdio>#define MAXSIZE 12500typedef struct{int i,j;int e;}Triple;typedef struct{Triple data[MAXSIZE+1];int mu,nu,tu;//存储矩阵的行数、列数、非零元个数 }TSMatrix;void input(TSMatrix &sm){for(int i=1;i<=sm.nu*sm.mu;i++)//【1】如果普通的转置算法写成sm.mu*sm.nu,压缩矩阵则要把判定条件改为:i<=sm.tuscanf("%d%d%d",&sm.data[i].i,&sm.data[i].j,&sm.data[i].e);//【2】注意要按照自己定义的结构体格式进行输入 }void print(TSMatrix sm){int index=1;for(int i=1;i<=sm.mu;i++){for(int j=1;j<=sm.nu;j++){ printf("%d\t",sm.data[index].e);index++;} printf("\n"); }}//稀疏矩阵的转置操作//按照矩阵M的列序进行转置 int TransposeSMatrix(TSMatrix M,TSMatrix &T){T.nu=M.mu;T.mu=M.nu;T.tu=M.tu;if(T.tu){int q=1;for(int col=1;col<=M.nu;col++)for(int p=1;p<=M.tu;p++)if(M.data[p].j==col){T.data[q].i=M.data[p].j;T.data[q].j=M.data[p].i;T.data[q].e=M.data[p].e;++q;} }return 1;} int main(){freopen("input1.txt","r",stdin);freopen("input2.txt","r",stdin);//printf("请输入矩阵的行数、列数、非零元素的个数:\n");printf("原矩阵为:\n");TSMatrix sm,ms;scanf("%d%d%d",&sm.mu,&sm.nu,&sm.tu);input(sm);print(sm);TransposeSMatrix(sm,ms);printf("转置完:\n");print(ms);return 0;}
测试实例:
input1.txt(m!=n)
2 3 61 1 11 2 21 3 02 1 42 2 02 3 6input2.txt(m=n)
3 3 91 1 11 2 21 3 32 1 42 2 52 3 63 1 73 2 83 3 9
打印出来的效果是:
然鹅其实应该是:
但是本来书中介绍的重点是矩阵的压缩,即不为矩阵中的0元素分配存储空间。但是最初上面的方法还是消耗了存储“0”元素的存储空间。后来上网一看别人的代码,才发现自己误解了,虽然用自己的编写的输入输出函数实现了矩阵的转置操作,但是并没能实现矩阵的“压缩”。因此,算法问题还是要具体问题具体分析。不能带着做工程的思想去学算法,一开始总是很难建立一个全面的体系的,而要顺着思路往下走。学算法要尝试着先去接受它,熟悉它的应用场景,再尝试记忆。不懂的多用笔演算、多带入。这也算是今天的一大收获吧,花了将近两个小时找Bug……
阅读全文