-
2021-05-21 19:01:11
/*****************稀疏矩阵运算器 ****************/
#include
#include
#define OK 1
#define TRUE 1
#define ERROR 0
#define FALSE 0
#define MAX_SIZE 100
typedef struct{ //构造三元组
int x;
int y;
int e;
}Triad;
typedef struct {
int mrow,mcol,ms;
Triad data[MAX_SIZE];
}Rtriad;
void Input(Rtriad &S){ //以三元组方式输入矩阵
printf("请输入行,列(row col):");
scanf("%d%d",&S.mrow,&S.mcol);
printf("请以行序为主序,以三元组的方式输入矩阵元素,'-1 -1 -1'表示结束:\n");
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
S.ms=0;
while(!(x==-1&&y==-1&&z==-1)){ //长度为S.ms+1,从0开始到S.ms
S.data[S.ms].x=x;
S.data[S.ms].y=y;
S.data[S.ms].e=z;
S.ms++;
scanf("%d%d%d",&x,&y,&z);
}
S.ms--;
}
void Add(Rtriad S1,Rtriad S2,Rtriad &S3){ //矩阵相加
if(S1.mcol!=S2.mcol||S1.mrow!=S2.mrow){
printf("ERROR!!!\n");
return ;
}
S3.mcol=S1.mcol ;
S3.mrow=S1.mrow ;
S3.ms=0;
int row,col,s,x,y,z;
for(row=1;row<=S3.mrow;row++){
for(col=1;col<=S3.mcol;col++){
z=0;
for(s=0;s<=S1.ms;s++){
if(S1.data[s].x==row&&S1.data[s].y==col){
S3.data[S3.ms].x=row;
S3.data[S3.ms].y=col;
S3.data[S3.ms].e=S1.data[s].e;
z++;
}
}
for(s=0;s<=S2.ms;s++){
if(S2.data[s].x==row&&S2.data[s].y==col){
S3.data[S3.ms].x=row;
S3.data[S3.ms].y=col;
if(z==0)
S3.data[S3.ms].e=S2.data[s].e;
else
S3.data[S3.ms].e+=S2.data[s].e;
z++;
}
}
if(z!=0)
S3.ms++;
}
}
int m=0;
for(int t=0;t<=S3.ms;t++){
if(S3.data[t].e==0){ //删除
for(int i=t+1;i
S3.data[i-1]=S3.data[i];
}
m++;
}
}
S3.ms-=m;
}
void Printf(Rtriad S){ //打印矩阵
int a[S.mrow][S.mcol];
for(int i=0;i
for(int j=0;j
a[i][j]=0;
for(int k=0;k<=S.ms;k++)
a[S.data[k].x-1][S.data[k].y-1]=S.data[k].e;
//printf("\n\n矩阵为:\n");
for(int i=0;i
for(int j=0;j
printf("%-2d ",a[i][j]);
printf("\n");
}
}
void Sub(Rtriad S1,Rtriad S2,Rtriad &S3){ //矩阵相减
for(int i=0;i<=S2.ms;i++)
S2.data[i].e*=-1;
Add(S1,S2,S3);
for(int i=0;i<=S2.ms;i++)
S2.data[i].e*=-1;
}
void Mult(Rtriad S1,Rtriad S2,Rtriad &S3){ //矩阵相乘
if(S1.mcol!=S2.mrow){
printf("ERROR!!!\n");
return ;
}
S3.mrow=S1.mrow;
S3.mcol=S2.mcol;
S3.ms=0;
int s1[S1.mrow][S1.mcol];
int s2[S2.mrow][S2.mcol];
int s3[S3.mrow][S3.mcol];
for(int i=0;i
for(int j=0;j
s1[i][j]=0;
for(int i=0;i
for(int j=0;j
s2[i][j]=0;
for(int i=0;i
for(int j=0;j
s3[i][j]=0;
for(int k=0;k<=S1.ms;k++)
s1[S1.data[k].x-1][S1.data[k].y-1]=S1.data[k].e;
for(int k=0;k<=S2.ms;k++)
s2[S2.data[k].x-1][S2.data[k].y-1]=S2.data[k].e;
for(int row=0;row
for(int col=0;col
for(int k=0;k
s3[row][col]+=(s1[row][k]*s2[k][col]);
if(s3[row][col]!=0){
S3.data[S3.ms].x=row+1;
S3.data[S3.ms].y=col+1;
S3.data[S3.ms].e=s3[row][col];
S3.ms++;
}
}
}
}
void Tran(Rtriad &S1,Rtriad &S2){ //矩阵的快速转置
S2.ms=S1.ms;
S2.mcol=S1.mrow;
S2.mrow=S1.mcol;
int num[MAX_SIZE]; //每一列的元素个数 ,从1开始计数
int pos[MAX_SIZE];
for(int col=1;col<=S1.mcol;col++) //初始化num
num[col]=0;
for(int i=0;i<=S1.ms;i++) //给num赋值 ,num从1开始
num[S1.data[i].y]++;
pos[1]=1; //给pos赋值 ,pos从1开始
for(int col=2;col<=S1.mcol;col++)
pos[col]=pos[col-1]+num[col-1];
for(int k=0;k<=S1.ms;k++){ //S1,S2都是从data[0]开始的
int col=S1.data[k].y;
int q=pos[col];
S2.data[q-1].e=S1.data[k].e;
S2.data[q-1].x=S1.data[k].y;
S2.data[q-1].y=S1.data[k].x;
pos[col]++;
}
}
int main(){
printf("/*****************稀疏矩阵运算器 ****************/\n\n");
printf("功能选择:\n1.矩阵相加\n2.矩阵相减\n3.矩阵相乘\n4.矩阵转置\n");
int n;
printf("选择功能:");
scanf("%d",&n);
Rtriad S1,S2,S3;
switch(n){
case 1:
printf("\n请输入矩阵1:\n");
Input(S1);
printf("\n请输入矩阵2:\n");
Input(S2);
Add(S1,S2,S3);
printf("\n结果为:\n");
Printf(S3);
break;
case 2:
printf("\n请输入矩阵1:\n");
Input(S1);
printf("\n请输入矩阵2:\n");
Input(S2);
Sub(S1,S2,S3);
printf("\n结果为:\n");
Printf(S3);
break;
case 3:
printf("\n请输入矩阵1:\n");
Input(S1);
printf("\n请输入矩阵2:\n");
Input(S2);
Mult(S1,S2,S3);
printf("\n结果为:\n");
Printf(S3);
break;
case 4:
printf("\n请输入矩阵1:\n");
Input(S1);
Tran(S1,S2);
printf("\n结果为:\n");
Printf(S3);
break;
}
return 0;
}
更多相关内容 -
稀疏矩阵运算器
2017-03-14 22:48:22printf("输入稀疏矩阵A的行数,列数和非零元个数:"); scanf("%d %d %d",&A.m,&A.n,&A.t); for(k=1;k;k++) { printf("输入第%d个非0元素的行数,列数和值:",k); scanf("%d %d %d",&A.data[k].i,&A.data[k].j,&... -
数据结构:稀疏矩阵运算器
2021-05-21 06:11:13按照教科书《数据结构(C语言版)》(严蔚敏等)5.3.2节中描述的方法,以十字链表表示稀疏矩阵。一、需求分析稀疏矩阵是指那些多数元素为零的矩阵。利用“稀疏”特点进修学校储存和计算可以大大节省储存空间,提高计算...题目:设计一个程序,实现一个能进行稀疏矩阵基本运算的计算器。按照教科书《数据结构(C语言版)》(严蔚敏等)5.3.2节中描述的方法,以十字链表表示稀疏矩阵。
一、需求分析
稀疏矩阵是指那些多数元素为零的矩阵。利用“稀疏”特点进修学校储存和计算可以大大节省储存空间,提高计算效率。实现一个能进行稀疏矩阵基本运算的计算器。
以“带行逻辑链接信息”的三元组顺序表表示稀疏矩阵,实现两个矩阵相加、相减和相乘的运算。稀疏矩阵的输入形式采用三元组表示,而运算结果的矩阵则以通常的阵列形式列出。
测试数据
\left[ \begin{matrix} 10&0& 0 \\ 0&0&9 \\ -1&0&0 \\ \end{matrix}\right] + \left[ \begin{matrix} 0&0& 0 \\ 0&0&-1 \\ 1&0&-3 \\ \end{matrix}\right]= \left[ \begin{matrix} 10&0& 0 \\ 0&0&8 \\ 0&0&-3 \\ \end{matrix}\right]
\left[ \begin{matrix} 10&9 \\ 0&9 \\ -1&0 \\ \end{matrix}\right] - \left[ \begin{matrix} 0&0 \\ 0&-1 \\ 1&-3 \\ \end{matrix}\right]= \left[ \begin{matrix} 10&0 \\ 0&10 \\ -2&-3 \\ \end{matrix}\right]
\left[ \begin{matrix} 4&-3&0&0&1 \\ 0&0&0&8&0 \\ 0&0&1&0&0 \\ 0&0&0&0&0 \end{matrix}\right] \times \left[ \begin{matrix} 3&0&0 \\ 4&2&0 \\ 0&1&0 \\ 1&0&0 \\ 0&0&0 \end{matrix}\right] = \left[ \begin{matrix} 0&-6&0 \\ 8&0&0 \\ 0&1&0 \\ 0&0&0 \end{matrix}\right]
二、概要设计
1.数据结构
ADT SparseMatrix{
数据对象:D={ aij | i = 1,2,...,m; j = 1,2,...,n;
aij∈ElemSet, m和n分别为矩阵的行数和列数}
数据关系:R={Row,Col}
Row={|1≤i≤m,1≤j≤n-1 }
Col={|1≤i≤m-1,1≤j≤n }
基本操作:
CreateSMatrix(&M)
操作结果:创建稀疏矩阵M。
PrintSMatrix(M)
初始条件:稀疏矩阵M存在。
操作结果: 输出稀疏矩阵M。
AddSMatrix(M, N, &Q)
初始条件:稀疏矩阵M与N的行数和列数对应相等。
操作结果:求稀疏矩阵的和Q=M+N。
SubtSMatrix(M, N, &Q)
初始条件:稀疏矩阵M与N的行数和列数对应相等。
操作结果:求稀疏矩阵的差Q=M-N。
MultSMatrix(M, N, &Q)
初始条件:稀疏矩阵M的列数等于N的行数。
操作结果:求稀疏矩阵乘积Q=M*N。
}ADT SparseMatrix
2. 使用函数
(1)行逻辑链接的顺序表
int CreateSMatrix(RLSMatrix *M)
操作结果:创建稀疏矩阵
int PrintSMatrix(RLSMatrix M)
操作结果:打印稀疏矩阵
int AddSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix *Q)
操作结果:稀疏矩阵加法,Q=M+N
int SubSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix *Q)
操作结果:稀疏矩阵减法,Q=M-N
int MultSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix *Q)
操作结果:稀疏矩阵乘法,Q=M*N
(2)十字链表
int CreateSMatrix_OL(CrossList *M)
操作结果:创建稀疏矩阵
int PrintSMatrix_OL(CrossList M)
操作结果:打印稀疏矩阵
int AddSMatrix_OL(CrossList *A, CrossList *B)
操作结果:将稀疏矩阵B加到稀疏矩阵A上
int SubSMatrix_OL(CrossList *A, CrossList *B)
操作结果:在稀疏矩阵A上减去稀疏矩阵B
int MultSMatrix_OL(CrossList A, CrossList B, CrossList *C)
操作结果:稀疏矩阵乘法,C=A*B
三、详细设计
1. 数据储存结构
(1)行逻辑链接顺序表
#define MAXSIZE 400 // 最大非零元个数
#define MAXRC 20 // 最大行数和列数
typedef struct{
int i,j; // 该非零元的行下标和列下标
int e;
}Triple;
typedef struct{
Triple data[MAXSIZE+1]; // 非零元三元组表
int rpos[MAXRC+1]; // 各行第一个非零元位置表
int mu,nu,tu; // 矩阵行数、列数和非零元个数
}RLSMatrix;
(2)十字链表
#define MAXSIZE 400 // 最大非零元个数
#define MAXRC 20 // 最大行数和列数
typedef struct OLNode{
int i,j; // 该非零元的行和列下标
int e;
struct OLNode *right, *down; // 该非零元所在行表和列表的后继链域
}OLNode, *OLink;
typedef struct {
OLink *rhead, *chead; // 行和列链表头指针向量基址由CreateSMatrix分配
int mu, nu, tu; // 稀疏矩阵行数、列数和非零元个数
}CrossList;
2.基本功能实现
2.1行逻辑链接顺序表
(1)稀疏矩阵创建
分别读入矩阵行数、列数以及非零元个数,同时提示输入各个非零元位置和数值,对于输入的非零元判断是否合法,并根据行号和列号进行以行为主序的储存,最后计算各行首个非零元位置。
int CreateSMatrix(RLSMatrix *M){
if(M) free(M);
int m,n,t;
do{
printf("输入矩阵行数,列数和非零元数目,用空格隔开\n");
scanf("%d %d %d", &m, &n, &t);
if(m < 0 || n < 0 || t < 0 || t > m*n){
printf("参数错误 \n");
}
}while(m < 0 || n < 0 || t < 0 || t > m*n);
M->mu = m; M->nu = n; M->tu = t;
printf("请按行优先输入三元组\n");
int i,j,e,k;
int p,q;
for(k = 1; k <= t; k++){
do{
printf("输入第%d个非零元的行号 列号 值, 用空格隔开\n",k);
scanf("%d %d %d", &i, &j, &e);
if(i <= 0 || j <= 0 || i > m || j > n|| e==0){
printf("参数错误\n");
}
}while(i <= 0 || j <= 0 || i > m || j > n|| e==0);
for(p = 1; p <= k-1 && (i > M->data[p].i || (i == M->data[p].i && j > M->data[p].j)); p++); //找到三元组插入的位置
for(q = k-1;q >= p; q--) M->data[q+1] = M->data[q]; //行序大的三元组依次向后移动
M->data[p].i = i;
M->data[p].j = j;
M->data[p].e = e;
}
int row,x;
int num[MAXRC + 1];
for(row = 1; row <= M->mu; ++row) num[row] = 0;
for(x = 1; x <= M->tu; ++x) ++num[M->data[x].i]; // 每一行非零元个数
M->rpos[1] = 1;
for(row = 2; row<=M->mu; ++row) M->rpos[row] = M->rpos[row-1] + num[row-1]; // 各行首个非零元位置
return 1;
}
(2)稀疏矩阵加减法
加减法基本思路一致,这里以加法为例。找到M和N矩阵各行非零元素的起始和终末位置之后开始遍历,对列号相等和不等两种情况分别处理,并处理相加结果等于0的情况。
int AddSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix *Q){
int arow;
int p,q,s = 1;
int tp,tq;
if(M.mu != N.mu || M.nu != N.nu) return 0;
Q->mu = M.mu; Q->nu = M.nu;
for(arow = 1; arow <= M.mu; ++arow){
Q->rpos[arow] = Q->tu + 1;
p = M.rpos[arow]; q = N.rpos[arow];
if(arow < M.mu){
tp = M.rpos[arow + 1];
tq = N.rpos[arow + 1];
}
else{
tp = M.tu + 1;
tq = N.tu + 1;
}
while(p < tp && q < tq){
if(M.data[p].j != N.data[q].j){ // 列号不等
if(M.data[p].j < N.data[q].j){
Q->data[s].i = arow;
Q->data[s].j = M.data[p].j;
Q->data[s].e = M.data[p].e;
s++; p++; Q->tu++;
}else{
Q->data[s].i = arow;
Q->data[s].j = N.data[q].j;
Q->data[s].e = N.data[q].e;
s++; q++; Q->tu++;
}
}else{ // 列号相等
if(M.data[p].e + N.data[q].e != 0){ // 结果非零
Q->data[s].i = arow;
Q->data[s].j = M.data[p].j;
Q->data[s].e = M.data[p].e + N.data[q].e;
s++; q++; p++; Q->tu++;
}else{q++; p++;}
}
}
while(p < tp){
Q->data[s].i = arow;
Q->data[s].j = M.data[p].j;
Q->data[s].e = M.data[p].e;
p++; s++; Q->tu++;
}
while(q < tq){
Q->data[s].i = arow;
Q->data[s].j = N.data[q].j;
Q->data[s].e = N.data[q].e;
q++; s++; Q->tu++;
}
}
return 1;
}
(3)稀疏矩阵乘法
对于M中每个元素M.data[p]找到N中所有满足条件M.data[p].j=N.data[q].i的元素N.data[q],求得M.data[p].e * N.data[q].e,对Q中元素设计累计和变量,初值为零,扫描数组M,求得相应元素乘积累加到适当的求累计和变量上。Q中元素行号与M中元素行号一致,又M中元素以M的行序为主序,因此对Q进行逐行处理,先求得累计和的中间结果(Q的一行),再压缩储存到Q.data中去。
int MultSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix *Q){
// 求矩阵乘积Q=M×N,采用行逻辑链接储存表示
int arow,brow;
int p,q,t,tp;
int ccol;
int ctemp[MAXRC + 1];
if(M.nu != N.mu) return 0;
Q->mu = M.mu; Q->nu = N.nu; Q->tu = 0; // Q初始化
if(M.tu * N.tu != 0){ // Q是非零矩阵
for(arow = 1; arow <= M.mu; ++arow){ // 处理M的每一行
for(int i = 1; i <= N.nu; i++) ctemp[i] = 0; // 当前行各元素累加器清零
Q->rpos[arow] = Q->tu + 1;
if(arow < M.mu) tp = M.rpos[arow + 1];
else{tp = M.tu + 1;}
for(p = M.rpos[arow]; p
brow = M.data[p].j; // 找到对应元所在N中的行号
if(brow < N.mu) t = N.rpos[brow + 1];
else{t = N.tu + 1;}
for(q = N.rpos[brow]; q
ccol = N.data[q].j; // 乘积元素在Q中的列号
ctemp[ccol] += M.data[p].e * N.data[q].e;
}// for q
}// 求得Q中第crow(=arow)行的非零元
for(ccol = 1; ccol <= Q->nu; ++ccol){ //压缩储存改行非零元
if(ctemp[ccol]){
if(++Q->tu > MAXSIZE) return 0;
Q->data[Q->tu].i = arow;
Q->data[Q->tu].j = ccol;
Q->data[Q->tu].e = ctemp[ccol];
}// if
} // for ccol
}// for arow
}// if
return 1;
}// MultSMatrix
(4)稀疏矩阵输出
通过双重循环,打印稀疏矩阵中非零元和零元素
int PrintSMatrix(RLSMatrix M){
int row,col,t = 1;
for(row = 1; row <= M.mu; row++){
for(col = 1; col <= M.nu; col++){
if(M.data[t].i == row && M.data[t].j == col){
printf("%d\t",M.data[t].e);
t++;
}else{
printf("0\t");
}
}
printf("\n");
}
return 1;
}
2.2十字链表
(1)稀疏矩阵创建
读入矩阵行数、列数和非零元个数,同时提示输入各个非零元位置和数值,对于输入的非零元判断是否合法,生成结点并完成在行链表和列链表中的插入。
int CreateSMatrix_OL(CrossList *M){
if(M) free(M);
int c;
int m,n,t;
int i,j,k,e;
OLink p,q;
do{
printf("输入矩阵行数,列数和非零元数目,用空格隔开\n");
scanf("%d %d %d", &m, &n, &t);
if(m < 0 || n < 0 || t < 0 || t > m*n){
printf("参数错误 \n");
}
}while(m < 0 || n < 0 || t < 0 || t > m*n);
M->mu = m; M->nu = n; M->tu = t;
if(!(M->rhead = (OLink*)malloc((m+1)*sizeof(OLink)))) exit(-2);
if(!(M->chead = (OLink*)malloc((n+1)*sizeof(OLink)))) exit(-2);
for(c = 1; c <= M->mu; c++) M->rhead[c]=NULL; // 初始化行列头指针向量
for(c = 1; c <= M->nu; c++) M->chead[c]=NULL;
for(k = 1; k <= t; k++){ // 按任意顺序输入非零元
do{
printf("输入第%d个非零元的行号 列号 值, 用空格隔开\n",k);
scanf("%d %d %d", &i, &j, &e);
if(i <= 0 || j <= 0 || i > m || j > n|| e==0){
printf("参数错误\n");
}
}while(i <= 0 || j <= 0 || i > m || j > n|| e==0);
if(!(p = (OLNode*)malloc(sizeof(OLNode)))) exit(-2);
p->i = i; p->j = j; p ->e = e; // 生成结点
if(M->rhead[i] == NULL || M->rhead[i]->j > j){
p->right = M->rhead[i];
M->rhead[i] = p;
}else{ // 寻找行表中的插入位置
for(q = M->rhead[i]; (q->right) && (q->right->j < j); q = q->right);
p->right = q->right;
q->right = p;
} // 完成行插入
if(M->chead[j] == NULL || M->chead[j]->i > i){ // 寻找列表中的插入位置
p->down = M->chead[j];
M->chead[j] = p;
}else{
for(q = M->chead[j]; (q->down) && (q->down->i < i); q = q->down);
p->down = q->down;
q->down = p;
} // 完成列插入
}
return 1;
}
(2)稀疏矩阵加减法
加减法基本思路一致,这里以加法为例。
非空指针pa和pb分别指向矩阵A,B中行值相同的两个结点,pa==NULL表明矩阵A在改行没有非零元,分为以下四种情况:
若pa==NULL或pa->j>pb->i,则需要在A矩阵的链表中插入一个值为bij的结点,此时,需要改变同一行中前一结点的right域值,以及同一列中前一结点的down域值。
若pa->jj,则将pa指针向右推进一步
若pa->j==pb->j,且pa->e+pb->e!=0,则只要将aij+bij的值送到pa所指结点的e域即可,其他所有域的值都不变
若pa->j==pb->j,且pa->e+pb->e==0,则需要在A矩阵链表中删除pa所指结点,此时需要改变同一行中前一结点的right域值以及同一列前一结点的down阈值。
为了便于插入和删除节点,还需要设置一些辅助指针。其一是在A的行链表上设pre指针,指示pa所指结点的前驱结点;其二是在A的每一列的链表上设一个指针hl[j],其初值和列链表的头指针相同,即hl[j]=chead[j]
int AddSMatrix_OL(CrossList *A, CrossList *B){
OLink pa, pb, pre, p, hl[MAXRC + 1];
int i, j;
if(A->mu != B->mu || A->nu != B->nu) return 0;
for(j = 1; j <= A->nu; j++) hl[j] = A->chead[j];
for(i = 1; i <= A->mu; i++){
pa = A->rhead[i]; pb = B->rhead[i]; pre = NULL;
while(pb){
if(!(p = (OLNode*)malloc(sizeof(OLNode)))) exit(-2);
p->i = pb->i; p->j = pb->j; p->e = pb->e;
if(pa == NULL || pa->j > pb->j){ // 在A中插入pb所指结点的复制结点p
if(pre == NULL) A->rhead[p->i] = p;
else{pre->right = p; }
p->right = pa;
pre = p;
if(A->chead[p->j] == NULL || A->chead[p->j]->i > p->i){
p->down = A->chead[p->j];
A->chead[p->j] = p;
}else{ // 在hl[p->j]中找到新结点的前驱,插入结点
p->down = hl[p->j]->down;
hl[p->j]->down = p;
}
hl[p->j] = p;
pb = pb->right;
A->tu++;
}else if(pa && pa->j < pb->j){ // pa指向本行下一个非零结点
pre = pa;
pa = pa->right;
}else if(pa->j == pb->j){ // 加和
pa->e += pb->e;
if(pa->e == 0){ // 加和为0,删除结点,修改行表和列表相应指针
if(pre == NULL) A->rhead[pa->i] = pa->right;
else{pre->right = pa->right; }
p = pa; pa = pa->right;
if(A->chead[p->j] == p) A->chead[p->j] = hl[p->j] = p->down;
else{hl[p->j]->down = p->down; }
free(p);
pb = pb->right;
A->tu--;
}else{pre = pa; pa = pa->right; pb = pb->right; }
}
}
}
return 1;
}
(3)稀疏矩阵乘法
对于C中i行j列的元素,分别使p指向A中i行链表头指针,q指向B中j列链表头指针,累加和e置为零。p,q不为空时,
当p->j > q->i,q指针下移
当p->j < q->i,p指针右移
当p->j == q->i,对乘积累计求和,并移动指针
累加器e不为0时,则在矩阵C行列链表中插入节点p1,设置cpre和rpre分别指示行列链表中p1的前驱结点。
int MultSMatrix_OL(CrossList A, CrossList B, CrossList *C){
int i, j, e;
OLink p, q, p1, rpre, cpre;
if(A.nu != B.mu) return 0;
C->mu = A.mu; C->nu = B.nu; C->tu = 0; // 初始化矩阵C
if(!(C->rhead = (OLink*)malloc((C->mu+1)*sizeof(OLink)))) exit(-2);
if(!(C->chead = (OLink*)malloc((C->nu+1)*sizeof(OLink)))) exit(-2);
for(i = 1; i <= C->mu; i++) C->rhead[i] = NULL;
for(j = 1; j <= C->nu; j++) C->chead[j] = NULL;
for(i = 1; i <= C->mu; i++){
for(j = 1; j <= C->nu; j++){
p = A.rhead[i]; q = B.chead[j]; e = 0; // p,q分别指向A中该行链表头指针,B中该列链表头指针
while(p && q){
if(p->j > q->i){
q = q->down;
}else if(p->j < q->i){
p = p->right;
}else{
e += p->e * q->e; // 乘积累加
q = q->down;
p = p->right;
}
}
if(e){ // 累加不为0
C->tu++;
if(!(p1 = (OLNode*)malloc(sizeof(OLNode)))) exit(-2);
p1->i = i; p1->j = j; p1->e = e;
p1->right = NULL; p1->down = NULL;
// 行插入
if(C->rhead[i] == NULL) {C->rhead[i] = p1; rpre = p1;}
else{rpre->right = p1; rpre = p1; }
// 列插入
if(C->chead[j] == NULL) {C->chead[j] = p1; cpre = p1;}
else{cpre->down = p1; cpre = p1; }
}
}
}
return 1;
}
(4)稀疏矩阵输出
通过双重循环,打印稀疏矩阵中非零元和零元素
int PrintSMatrix_OL(CrossList M){
OLink p;
int row,col;
for(row = 1; row <= M.mu; row++){
if(M.rhead[row]){
p = M.rhead[row];
for(col = 1; col <= M.nu; col++){
if(p->i == row && p->j == col && p != NULL){
printf("%d\t",p->e);
if(p->right) p = p->right;
}else{printf("0\t");}
}
}else{for(col = 1; col <= M.nu; col++) printf("0\t");}
printf("\n");
}
return 1;
}
4.主程序
通过读入操作序号来进行相应操作,在满足操作对应条件下进行相应操作,并打印结果,两种储存方式下主程序结构基本一致,只是运算时调用函数不同。
int main(){
int num;
CrossList M, N, Q;
do{
printf("操作:1.矩阵相加 2.矩阵相减 3.矩阵相乘 4.退出\n");
scanf("%d",&num);
if(num == 1 || num == 2 || num == 3){
printf("请输入矩阵1\n");
CreateSMatrix_OL(&M);
printf("请输入矩阵2\n");
CreateSMatrix_OL(&N);
printf("两矩阵为:\n");
PrintSMatrix_OL(M);
printf("\n");
PrintSMatrix_OL(N);
switch(num){
case 1:
{
if(AddSMatrix_OL(&M, &N)){
printf("结果:\n");
PrintSMatrix_OL(M);
}
else {printf("参数错误\n");}
break;
}
case 2:
{
if(SubSMatrix_OL(&M, &N)){
printf("结果:\n");
PrintSMatrix_OL(M);
}
else {printf("参数错误\n");}
break;
}
case 3:
{
if(MultSMatrix_OL(M,N,&Q)){
printf("结果:\n");
PrintSMatrix_OL(Q);
}
else {printf("参数错误\n");}
break;
}
default: break;
}
}
}while(num == 1 || num == 2 || num == 3);
return 1;
}
5.程序的层次结构
层次结构
四、用户手册
本程序的运行环境为DOS操作系统,执行文件为:sparsematrix.exe和crossmatrix.exe 分别对应行逻辑链接顺序表和十字链表实现的稀疏矩阵计算器
进入程序按提示操作,输入要进行操作对应的序号
根据操作提示输入两矩阵的行数、列数和非零元个数,并输入非零元的行号,列号以及值
结果打印
根据操作提示退出程序
五、测试结果
\left[ \begin{matrix} 10&0& 0 \\ 0&0&9 \\ -1&0&0 \\ \end{matrix}\right] + \left[ \begin{matrix} 0&0& 0 \\ 0&0&-1 \\ 1&0&-3 \\ \end{matrix}\right]= \left[ \begin{matrix} 10&0& 0 \\ 0&0&8 \\ 0&0&-3 \\ \end{matrix}\right]
\left[ \begin{matrix} 10&9 \\ 0&9 \\ -1&0 \\ \end{matrix}\right] - \left[ \begin{matrix} 0&0 \\ 0&-1 \\ 1&-3 \\ \end{matrix}\right]= \left[ \begin{matrix} 10&0 \\ 0&10 \\ -2&-3 \\ \end{matrix}\right]
\left[ \begin{matrix} 4&-3&0&0&1 \\ 0&0&0&8&0 \\ 0&0&1&0&0 \\ 0&0&0&0&0 \end{matrix}\right] \times \left[ \begin{matrix} 3&0&0 \\ 4&2&0 \\ 0&1&0 \\ 1&0&0 \\ 0&0&0 \end{matrix}\right] = \left[ \begin{matrix} 0&-6&0 \\ 8&0&0 \\ 0&1&0 \\ 0&0&0 \end{matrix}\right]
测试结果1
测试结果2
测试结果3
六、源代码
sparsematrix.c
#include
#include
#define MAXSIZE 400
#define MAXRC 20
typedef struct{
int i,j;
int e;
}Triple;
typedef struct{
Triple data[MAXSIZE+1];
int rpos[MAXRC+1];
int mu,nu,tu; // 行,列,非零元个数
}RLSMatrix;
int CreateSMatrix(RLSMatrix *M){
if(M) free(M);
int m,n,t;
do{
printf("输入矩阵行数,列数和非零元数目,用空格隔开\n");
scanf("%d %d %d", &m, &n, &t);
if(m < 0 || n < 0 || t < 0 || t > m*n){
printf("参数错误 \n");
}
}while(m < 0 || n < 0 || t < 0 || t > m*n);
M->mu = m; M->nu = n; M->tu = t;
printf("请按行优先输入三元组\n");
int i,j,e,k;
int p,q;
for(k = 1; k <= t; k++){
do{
printf("输入第%d个非零元的行号 列号 值, 用空格隔开\n",k);
scanf("%d %d %d", &i, &j, &e);
if(i <= 0 || j <= 0 || i > m || j > n|| e==0){
printf("参数错误\n");
}
}while(i <= 0 || j <= 0 || i > m || j > n|| e==0);
for(p = 1; p <= k-1 && (i > M->data[p].i || (i == M->data[p].i && j > M->data[p].j)); p++); //找到此三元组插入的位置
for(q = k-1;q >= p; q--) M->data[q+1] = M->data[q]; //行序比它大的三元组依次向后移动
M->data[p].i = i;
M->data[p].j = j;
M->data[p].e = e;
}
int row,x;
int num[MAXRC + 1];
for(row = 1; row <= M->mu; ++row) num[row] = 0;
for(x = 1; x <= M->tu; ++x) ++num[M->data[x].i];
M->rpos[1] = 1;
for(row = 2; row<=M->mu; ++row) M->rpos[row] = M->rpos[row-1] + num[row-1];
return 1;
}
int PrintSMatrix(RLSMatrix M){
int row,col,t = 1;
for(row = 1; row <= M.mu; row++){
for(col = 1; col <= M.nu; col++){
if(M.data[t].i == row && M.data[t].j == col){
printf("%d\t",M.data[t].e);
t++;
}else{
printf("0\t");
}
}
printf("\n");
}
return 1;
}
int AddSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix *Q){
int arow;
int p,q,s = 1;
int tp,tq;
if(M.mu != N.mu || M.nu != N.nu) return 0;
Q->mu = M.mu; Q->nu = M.nu;
for(arow = 1; arow <= M.mu; ++arow){
Q->rpos[arow] = Q->tu + 1;
p = M.rpos[arow]; q = N.rpos[arow];
if(arow < M.mu){
tp = M.rpos[arow + 1];
tq = N.rpos[arow + 1];
}
else{
tp = M.tu + 1;
tq = N.tu + 1;
}
while(p < tp && q < tq){
if(M.data[p].j != N.data[q].j){ // 列号不等
if(M.data[p].j < N.data[q].j){
Q->data[s].i = arow;
Q->data[s].j = M.data[p].j;
Q->data[s].e = M.data[p].e;
s++; p++; Q->tu++;
}else{
Q->data[s].i = arow;
Q->data[s].j = N.data[q].j;
Q->data[s].e = N.data[q].e;
s++; q++; Q->tu++;
}
}else{ // 列号相等
if(M.data[p].e + N.data[q].e != 0){ // 结果非零
Q->data[s].i = arow;
Q->data[s].j = M.data[p].j;
Q->data[s].e = M.data[p].e + N.data[q].e;
s++; q++; p++; Q->tu++;
}else{q++; p++;}
}
}
while(p < tp){
Q->data[s].i = arow;
Q->data[s].j = M.data[p].j;
Q->data[s].e = M.data[p].e;
p++; s++; Q->tu++;
}
while(q < tq){
Q->data[s].i = arow;
Q->data[s].j = N.data[q].j;
Q->data[s].e = N.data[q].e;
q++; s++; Q->tu++;
}
}
return 1;
}
int SubSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix *Q){
int arow;
int p,q,s = 1;
int tp,tq;
if(M.mu != N.mu || M.nu != N.nu) return 0;
Q->mu = M.mu; Q->nu = M.nu;
for(arow = 1; arow <= M.mu; ++arow){
Q->rpos[arow] = Q->tu + 1;
p = M.rpos[arow]; q = N.rpos[arow];
if(arow < M.mu){
tp = M.rpos[arow + 1];
tq = N.rpos[arow + 1];
}
else{
tp = M.tu + 1;
tq = N.tu + 1;
}
while(p < tp && q < tq){
if(M.data[p].j != N.data[q].j){ // 列号不等
if(M.data[p].j < N.data[q].j){
Q->data[s].i = arow;
Q->data[s].j = M.data[p].j;
Q->data[s].e = M.data[p].e;
s++; p++; Q->tu++;
}else{
Q->data[s].i = arow;
Q->data[s].j = N.data[q].j;
Q->data[s].e = - N.data[q].e;
s++; q++; Q->tu++;
}
}else{ // 列号相等
if(M.data[p].e - N.data[q].e != 0){
Q->data[s].i = arow;
Q->data[s].j = M.data[p].j;
Q->data[s].e = M.data[p].e - N.data[q].e;
s++; q++; p++; Q->tu++;
}else{q++; p++;}
}
}
while(p < tp){
Q->data[s].i = arow;
Q->data[s].j = M.data[p].j;
Q->data[s].e = M.data[p].e;
p++; s++; Q->tu++;
}
while(q < tq){
Q->data[s].i = arow;
Q->data[s].j = N.data[q].j;
Q->data[s].e = - N.data[q].e;
q++; s++; Q->tu++;
}
}
return 1;
}
int MultSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix *Q){
// 求矩阵乘积Q=M×N,采用行逻辑链接储存表示
int arow,brow;
int p,q,t,tp;
int ccol;
int ctemp[MAXRC + 1];
if(M.nu != N.mu) return 0;
Q->mu = M.mu; Q->nu = N.nu; Q->tu = 0; // Q初始化
if(M.tu * N.tu != 0){ // Q是非零矩阵
for(arow = 1; arow <= M.mu; ++arow){ // 处理M的每一行
for(int i = 1; i <= N.nu; i++) ctemp[i] = 0; // 当前行各元素累加器清零
Q->rpos[arow] = Q->tu + 1;
if(arow < M.mu) tp = M.rpos[arow + 1];
else{tp = M.tu + 1;}
for(p = M.rpos[arow]; p
brow = M.data[p].j; // 找到对应元所在N中的行号
if(brow < N.mu) t = N.rpos[brow + 1];
else{t = N.tu + 1;}
for(q = N.rpos[brow]; q
ccol = N.data[q].j; // 乘积元素在Q中的列号
ctemp[ccol] += M.data[p].e * N.data[q].e;
}// for q
}// 求得Q中第crow(=arow)行的非零元
for(ccol = 1; ccol <= Q->nu; ++ccol){ //压缩储存改行非零元
if(ctemp[ccol]){
if(++Q->tu > MAXSIZE) return 0;
Q->data[Q->tu].i = arow;
Q->data[Q->tu].j = ccol;
Q->data[Q->tu].e = ctemp[ccol];
}// if
} // for ccol
}// for arow
}// if
return 1;
}// MultSMatrix
int main(){
int num;
RLSMatrix M, N, Q;
do{
printf("操作:1.矩阵相加 2.矩阵相减 3.矩阵相乘 4.退出\n");
scanf("%d",&num);
if(num == 1 || num == 2 || num == 3){
printf("请输入矩阵1\n");
CreateSMatrix(&M);
printf("请输入矩阵2\n");
CreateSMatrix(&N);
printf("两矩阵为:\n");
PrintSMatrix(M);
printf("\n");
PrintSMatrix(N);
switch(num){
case 1:
{
if(AddSMatrix(M,N,&Q)){
printf("结果:\n");
PrintSMatrix(Q);
}
else {printf("参数错误\n");}
break;
}
case 2:
{
if(SubSMatrix(M,N,&Q)){
printf("结果:\n");
PrintSMatrix(Q);
}
else {printf("参数错误\n");}
break;
}
case 3:
{
if(MultSMatrix(M,N,&Q)){
printf("结果:\n");
PrintSMatrix(Q);
}
else {printf("参数错误\n");}
break;
}
default: break;
}
}
}while(num == 1 || num == 2 || num == 3);
return 1;
}
crosmatrix.c
#include
#include
#define MAXSIZE 400
#define MAXRC 20
typedef struct OLNode{
int i,j;
int e;
struct OLNode *right, *down;
}OLNode, *OLink;
typedef struct {
OLink *rhead, *chead;
int mu, nu, tu;
}CrossList;
int CreateSMatrix_OL(CrossList *M){
if(M) free(M);
int c;
int m,n,t;
int i,j,k,e;
OLink p,q;
do{
printf("输入矩阵行数,列数和非零元数目,用空格隔开\n");
scanf("%d %d %d", &m, &n, &t);
if(m < 0 || n < 0 || t < 0 || t > m*n){
printf("参数错误 \n");
}
}while(m < 0 || n < 0 || t < 0 || t > m*n);
M->mu = m; M->nu = n; M->tu = t;
if(!(M->rhead = (OLink*)malloc((m+1)*sizeof(OLink)))) exit(-2);
if(!(M->chead = (OLink*)malloc((n+1)*sizeof(OLink)))) exit(-2);
for(c = 1; c <= M->mu; c++) M->rhead[c]=NULL;
for(c = 1; c <= M->nu; c++) M->chead[c]=NULL;
for(k = 1; k <= t; k++){
do{
printf("输入第%d个非零元的行号 列号 值, 用空格隔开\n",k);
scanf("%d %d %d", &i, &j, &e);
if(i <= 0 || j <= 0 || i > m || j > n|| e==0){
printf("参数错误\n");
}
}while(i <= 0 || j <= 0 || i > m || j > n|| e==0);
if(!(p = (OLNode*)malloc(sizeof(OLNode)))) exit(-2);
p->i = i; p->j = j; p ->e = e;
if(M->rhead[i] == NULL || M->rhead[i]->j > j){
p->right = M->rhead[i];
M->rhead[i] = p;
}else{
for(q = M->rhead[i]; (q->right) && (q->right->j < j); q = q->right);
p->right = q->right;
q->right = p;
}
if(M->chead[j] == NULL || M->chead[j]->i > i){
p->down = M->chead[j];
M->chead[j] = p;
}else{
for(q = M->chead[j]; (q->down) && (q->down->i < i); q = q->down);
p->down = q->down;
q->down = p;
}
}
return 1;
}
int PrintSMatrix_OL(CrossList M){
OLink p;
int row,col;
for(row = 1; row <= M.mu; row++){
if(M.rhead[row]){
p = M.rhead[row];
for(col = 1; col <= M.nu; col++){
if(p->i == row && p->j == col && p != NULL){
printf("%d\t",p->e);
if(p->right) p = p->right;
}else{printf("0\t");}
}
}else{for(col = 1; col <= M.nu; col++) printf("0\t");}
printf("\n");
}
return 1;
}
int AddSMatrix_OL(CrossList *A, CrossList *B){
OLink pa, pb, pre, p, hl[MAXRC + 1];
int i, j;
if(A->mu != B->mu || A->nu != B->nu) return 0;
for(j = 1; j <= A->nu; j++) hl[j] = A->chead[j];
for(i = 1; i <= A->mu; i++){
pa = A->rhead[i]; pb = B->rhead[i]; pre = NULL;
while(pb){
if(!(p = (OLNode*)malloc(sizeof(OLNode)))) exit(-2);
p->i = pb->i; p->j = pb->j; p->e = pb->e;
if(pa == NULL || pa->j > pb->j){
if(pre == NULL) A->rhead[p->i] = p;
else{pre->right = p; }
p->right = pa;
pre = p;
if(A->chead[p->j] == NULL || A->chead[p->j]->i > p->i){
p->down = A->chead[p->j];
A->chead[p->j] = p;
}else{
p->down = hl[p->j]->down;
hl[p->j]->down = p;
}
hl[p->j] = p;
pb = pb->right;
A->tu++;
}else if(pa && pa->j < pb->j){
pre = pa;
pa = pa->right;
}else if(pa->j == pb->j){
pa->e += pb->e;
if(pa->e == 0){
if(pre == NULL) A->rhead[pa->i] = pa->right;
else{pre->right = pa->right; }
p = pa; pa = pa->right;
if(A->chead[p->j] == p) A->chead[p->j] = hl[p->j] = p->down;
else{hl[p->j]->down = p->down; }
free(p);
pb = pb->right;
A->tu--;
}else{pre = pa; pa = pa->right; pb = pb->right; }
}
}
}
return 1;
}
int SubSMatrix_OL(CrossList *A, CrossList *B){
OLink pa, pb, pre, p, hl[MAXRC + 1];
int i, j;
if(A->mu != B->mu || A->nu != B->nu) return 0;
for(j = 1; j <= A->nu; j++) hl[j] = A->chead[j];
for(i = 1; i <= A->mu; i++){
pa = A->rhead[i]; pb = B->rhead[i]; pre = NULL;
while(pb){
if(!(p = (OLNode*)malloc(sizeof(OLNode)))) exit(-2);
p->i = pb->i; p->j = pb->j; p->e = - pb->e;
if(pa == NULL || pa->j > pb->j){
if(pre == NULL) A->rhead[p->i] = p;
else{pre->right = p; }
p->right = pa;
pre = p;
if(A->chead[p->j] == NULL || A->chead[p->j]->i > p->i){
p->down = A->chead[p->j];
A->chead[p->j] = p;
}else{
p->down = hl[p->j]->down;
hl[p->j]->down = p;
}
hl[p->j] = p;
pb = pb->right;
A->tu++;
}else if(pa && pa->j < pb->j){
pre = pa;
pa = pa->right;
}else if(pa->j == pb->j){
pa->e -= pb->e;
if(pa->e == 0){
if(pre == NULL) A->rhead[pa->i] = pa->right;
else{pre->right = pa->right; }
p = pa; pa = pa->right;
if(A->chead[p->j] == p) A->chead[p->j] = hl[p->j] = p->down;
else{hl[p->j]->down = p->down; }
free(p);
pb = pb->right;
A->tu--;
}else{pre = pa; pa = pa->right; pb = pb->right; }
}
}
}
return 1;
}
int MultSMatrix_OL(CrossList A, CrossList B, CrossList *C){
int i, j, e;
OLink p, q, p1, rpre, cpre;
if(A.nu != B.mu) return 0;
C->mu = A.mu; C->nu = B.nu; C->tu = 0;
if(!(C->rhead = (OLink*)malloc((C->mu+1)*sizeof(OLink)))) exit(-2);
if(!(C->chead = (OLink*)malloc((C->nu+1)*sizeof(OLink)))) exit(-2);
for(i = 1; i <= C->mu; i++) C->rhead[i] = NULL;
for(j = 1; j <= C->nu; j++) C->chead[j] = NULL;
for(i = 1; i <= C->mu; i++){
for(j = 1; j <= C->nu; j++){
p = A.rhead[i]; q = B.chead[j]; e = 0;
while(p && q){
if(p->j > q->i){
q = q->down;
}else if(p->j < q->i){
p = p->right;
}else{
e += p->e * q->e;
q = q->down;
p = p->right;
}
}
if(e){
C->tu++;
if(!(p1 = (OLNode*)malloc(sizeof(OLNode)))) exit(-2);
p1->i = i; p1->j = j; p1->e = e;
p1->right = NULL; p1->down = NULL;
// 行插入
if(C->rhead[i] == NULL) {C->rhead[i] = p1; rpre = p1;}
else{rpre->right = p1; rpre = p1; }
// 列插入
if(C->chead[j] == NULL) {C->chead[j] = p1; cpre = p1;}
else{cpre->down = p1; cpre = p1; }
}
}
}
return 1;
}
int main(){
int num;
CrossList M, N, Q;
do{
printf("操作:1.矩阵相加 2.矩阵相减 3.矩阵相乘 4.退出\n");
scanf("%d",&num);
if(num == 1 || num == 2 || num == 3){
printf("请输入矩阵1\n");
CreateSMatrix_OL(&M);
printf("请输入矩阵2\n");
CreateSMatrix_OL(&N);
printf("两矩阵为:\n");
PrintSMatrix_OL(M);
printf("\n");
PrintSMatrix_OL(N);
switch(num){
case 1:
{
if(AddSMatrix_OL(&M, &N)){
printf("结果:\n");
PrintSMatrix_OL(M);
}
else {printf("参数错误\n");}
break;
}
case 2:
{
if(SubSMatrix_OL(&M, &N)){
printf("结果:\n");
PrintSMatrix_OL(M);
}
else {printf("参数错误\n");}
break;
}
case 3:
{
if(MultSMatrix_OL(M,N,&Q)){
printf("结果:\n");
PrintSMatrix_OL(Q);
}
else {printf("参数错误\n");}
break;
}
default: break;
}
}
}while(num == 1 || num == 2 || num == 3);
return 1;
}
-
C语言编写的稀疏矩阵运算器
2011-11-29 15:32:40清华大学版《数据结构》第三次试验代码,原创 -
C语言实现稀疏矩阵
2020-08-30 11:56:59主要为大家详细介绍了C语言实现稀疏矩阵的代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 -
C语言实现的稀疏矩阵运算器
2010-04-30 10:05:11C语言实现的稀疏矩阵运算器,通过用数据结构来实现(一部分),主要是矩阵的实现 -
C语言数据结构两个稀疏矩阵相加
2019-04-30 18:27:20C语言数据结构之两个稀疏矩阵相加。代码中代码功能描述、输入输出说明和测试输出输入。 -
稀疏矩阵运算器.rar
2021-04-01 12:00:26实现任意两个稀疏矩阵的加、减和乘运算和任一稀疏矩阵的转置运算。 -
稀疏矩阵运算器的C语言程序
2009-12-23 20:23:04以“带行逻辑连接信息”的三元组顺序表表示稀疏矩阵,实现两矩阵相加,相减,相乘的运算。稀疏矩阵的输入用三元组表示,而运算结果以列阵形式列出。 -
稀疏矩阵的运算C语言——课程设计实习
2022-01-08 13:23:03实现一个能进行稀疏矩阵基本运算的运算器,具体功能有:以“带行逻辑链接信息”的三元组顺序表示稀疏矩阵,实现两个稀疏矩阵相加、相减、相乘的功能。稀疏矩阵的输入形式采用三元组表示,而运算结果的矩阵则以通常的...设计要求
稀疏矩阵是指那些多数元素为零的矩阵。利用“稀疏”特点进行存储和计算可以大大节省存储空间,提高计算准备效率。实现一个能进行稀疏矩阵基本运算的运算器,具体功能有:
- 以“带行逻辑链接信息”的三元组顺序表示稀疏矩阵,实现两个稀疏矩阵相加、相减、相乘的功能。
- 稀疏矩阵的输入形式采用三元组表示,而运算结果的矩阵则以通常的阵列形式列出。
- 稀疏矩阵采用带行逻辑链接信息的三元组顺序存储。
需求分析
- 设计函数建立稀疏矩阵,初始化值。
- 设计函数输出稀疏矩阵的值。
- 构造函数进行两个稀疏矩阵相加,输出最终的稀疏矩阵。
- 构造函数进行两个稀疏矩阵相减,输出最终的稀疏矩阵。
- 构造函数进行两个稀疏矩阵的相乘,输出最终的稀疏矩阵。
- 构造函数进行稀疏矩阵的转置,并输出结果。
- 退出系统。
概要设计
(1)主界面设计为了实现对稀疏矩阵的多种算法功能的管理,首先设计一个含有多个菜单项的主控菜单子程序以系统的各项子功能,方便用户交互式使用本系统。本系统主控菜单运行界面如图:
(2)存储结构设计本系统采用单链表结构存储稀疏矩阵的具体信息。其中:全部结点的信息用头结点为指针数组的单链表存储。
(3)系统功能设计本系统除了要完成稀疏矩阵的初始化功能外还设置了4个子功能菜单。建立稀疏矩阵用void Creat()实现,依据读入的行数和列数以及非零元素的个数,分别设定每个非零元素的信息。4个子功能的设计描述如下:- 稀疏矩阵的加法:此功能由函数void add( )实现,当用户选择该功能,系统即提示用户初始化要进行加法的两个矩阵的信息。然后进行加法,最后输出结果。
- 稀疏矩阵的减法:此功能由函数void sub( )实现。当用户选择该功能,系统提示输入要进行相减的两个矩阵的详细信息。然后进行相减,最后得到结果。
- 稀疏矩阵的乘法:此功能由函数void mult( )实现。当用户选择该功能,系统提示输入要进行相乘的两个矩阵的详细信息。然后进行相乘,最后得到结果。
- 系统程序的退出:即退出稀疏矩阵的应用系统。用户选择此功能时,系统会提示计算器已关闭,按任意键退出。
模块设计
- void creat(TSMatrix *T) /由用户输入创建稀疏矩阵/
- void print(TSMatrix A) /输出稀疏矩阵/
- void add(TSMatrix A,TSMatrix B) /加法运算/
- void sub(TSMatrix A,TSMatrix B) /减法运算/
- void mult(TSMatrix A,TSMatrix B,TSMatrix *c) /乘法运算/
- char menu() /计算器主界面(菜单)/
- int main() /功能主函数/
C语言源程序——建议使用Devc ++ 运行
#include<stdio.h> #include<math.h> #include<stdlib.h> #include<conio.h> #include<malloc.h> #include<string.h> #define MAXSIZE 100 /*假设非零元个数的最大值为100*/ #define MAXMU 20 /*稀疏矩阵最大行列值为20*/ int count = 1; typedef struct { int i,j; /*该非零元的行下标和列下标*/ int v; }Triple; typedef struct /*稀疏矩阵是由三元组的顺序存储*/ { int rpos[MAXMU+1]; /*各行第一个非零元素的位置表*/ Triple data[MAXSIZE+1]; /*非零元三元组顺序表,data[0]未使用*/ int mu,nu,tu; /*矩阵的行数,列数和非零元个数*/ }TSMatrix; void creat(TSMatrix *T) /*由用户输入创建稀疏矩阵*/ { int row,num,k; do { system("cls"); printf("\n 请输入第%d个矩阵!\n",count); count = count + 1; printf("*********************************\n"); printf(" 请输入稀疏矩阵行数: " ); scanf("%d", &T->mu); if (T->mu<0 || T->mu>MAXMU) printf("\n 行数超出定义范围,请重新输入!\n"); } while (T->mu<0 || T->mu>MAXMU); do { printf(" 请输入稀疏矩阵列数: "); scanf("%d", &T->nu); if (T->nu<0 || T->nu>MAXMU) printf("\n 列数超出定义范围,请重新输入!\n"); } while (T->nu<0 || T->nu>MAXMU); do { printf(" 请输入稀疏矩阵的非零元素个数: "); scanf("%d", &T->tu); if (T->tu>MAXSIZE || (T->tu>T->mu*T->nu)) printf("\n 非零元素个数超出定义范围,请重新输入!\n"); } while (T->tu>MAXSIZE || (T->tu>T->mu*T->nu)); printf("**********************************\n"); printf(" 请按行从小到大依次输入结点信息!\n"); for (k=1; k<=T->tu; k++) { do { printf(" 请按三元组存储输入第%d个非零元素的行数i:", k); scanf("%d", &T->data[k].i); if (!T->data[k].i || T->data[k].i>T->mu) printf("\n 输入有误,请重新输入!\n"); } while ((!T->data[k].i || T->data[k].i>T->mu)); do { printf(" 请按三元组存储输入第%d个非零元素的列数j:", k); scanf("%d", &T->data[k].j); if (!T->data[k].j || T->data[k].j>T->nu) printf("\n 输入有误,请重新输入!\n"); } while ((!T->data[k].j || T->data[k].j>T->nu)); do { printf(" 请按三元组存储输入第%d个非零元素的值v:", k); scanf("%d", &T->data[k].v); if (T->data[k].v==0) printf("\n 输入有误,请重新输入!\n"); } while (T->data[k].v==0); printf("***********************************\n"); } for(row=1,num=1;row<=T->mu;row++) /*行逻辑链接信息存储*/ { T->rpos[row]=num; while(T->data[num].i==row) num++; } return; } void print(TSMatrix A) /*输出稀疏矩阵*/ { int q,n,k,a=0; system("cls"); printf("\n\n经过稀疏矩阵运算器运算,所得结果为:\n"); printf("***********************************\n"); printf("***********************************\n"); for(n=1;n<=A.mu;n++) { for(k=1;k<=A.nu;k++) { for(q=1;q<=A.tu;q++) if(A.data[q].i==n && A.data[q].j==k) { printf("\t%-3d",A.data[q].v);break; } if(q>A.tu) printf("\t%-3d",a); } printf("\n"); } printf("***********************************\n"); printf("***********************************\n"); } void add(TSMatrix A,TSMatrix B) /*加法运算*/ { int n,k; if(A.mu!=B.mu || A.nu!=B.nu) { printf("\n 不满足矩阵相加条件!"); printf("\n 需满足两矩阵的行数、列数均对应相等方可进行加法运算!!"); } else { for(n=1;n<=A.tu;n++) for(k=1;k<=B.tu;k++) /*将矩阵A的非零元接至B中*/ if(A.data[n].i==B.data[k].i && A.data[n].j==B.data[k].j) { A.data[n].v+=B.data[k].v; B.data[k].v=0; } for(k=1;k<=B.tu;k++) if(B.data[k].v!=0) { A.data[A.tu+1].i=B.data[k].i; A.data[A.tu+1].j=B.data[k].j; A.data[A.tu+1].v=B.data[k].v; A.tu++; } print(A); } } void sub(TSMatrix A,TSMatrix B) /*减法运算*/ { int n,k; if(A.mu!=B.mu || A.nu!=B.nu) { printf("\n 不满足矩阵相减条件!"); printf("\n 需要满足两矩阵的行数、列数均对应相等方可进行减法运算!!"); } else { for(n=1;n<=A.tu;n++) for(k=1;k<=B.tu;k++) /*将矩阵A的非零元接至B中*/ if(A.data[n].i==B.data[k].i && A.data[n].j==B.data[k].j) { A.data[n].v-=B.data[k].v; B.data[k].v=0; } for(k=1;k<=B.tu;k++) if(B.data[k].v!=0) { A.data[A.tu+1].i=B.data[k].i; A.data[A.tu+1].j=B.data[k].j; A.data[A.tu+1].v=-B.data[k].v; A.tu++; } print(A); } } void mult(TSMatrix A,TSMatrix B,TSMatrix *c) /*乘法运算*/ { int arow,tp,i,t; int ccol,p,brow,q; int ctemp[MAXMU+1]; if(A.nu!=B.mu) { printf(" 矩阵不满足相乘条件!"); return ; } c->mu=A.mu; c->nu=B.nu; c->tu=0; if(A.tu==0||B.tu==0) { printf(" 结果矩阵为零!"); return ; } else { for(arow=1;arow<=A.mu;arow++) { for(i=0;i<MAXMU;i++) /*存储器清零*/ ctemp[i]=0; c->rpos[arow]=c->tu+1; if(arow<A.mu) tp=A.rpos[arow+1]; else tp=A.tu+1; for(p=A.rpos[arow];p<tp;p++) { brow=A.data[p].j; if(brow<B.mu) t=B.rpos[brow+1]; else t=B.tu+1; for(q=B.rpos[brow];q<t;q++) { ccol=B.data[q].j; ctemp[ccol]+=A.data[p].v*B.data[q].v; } } for(ccol=1;ccol<=c->nu;ccol++) if(ctemp[ccol]) { if(++(c->tu)>MAXSIZE) { printf("超出范围!"); return ; } c->data[c->tu].v=ctemp[ccol]; c->data[c->tu].i=arow; c->data[c->tu].j=ccol; } } } print(*c); } char menu() /*计算器主界面(菜单)*/ { char n; system("title 稀疏矩阵运算器"); system("cls"); system("mode con cols=70 lines=30"); printf("\n"); printf("\n 课程设计-----*******班 \n\n\n\n"); printf(" **************************************** \n"); printf(" * * \n"); printf(" * 稀 疏 矩 阵 运 算 器 * \n"); printf(" * * \n"); printf(" * 实 现 运 算 * \n"); printf(" * * \n"); printf(" * 1:矩阵相加 * \n"); printf(" * 2:矩阵相減 * \n"); printf(" * 3:矩阵相乘 * \n"); printf(" * 4:选择退出 * \n"); printf(" * * \n"); printf(" **************************************** \n"); printf(" 请输入序号进行操作 : \n"); printf(" ");n=getchar(); return n; } int main() /*功能主函数*/ { TSMatrix A,B,C; for(;;) switch(menu()) {case '1':creat(&A); creat(&B); add(A,B); getch(); break; case '2':creat(&A); creat(&B); sub(A,B); getch(); break; case '3':creat(&A); creat(&B); mult(A,B,&C); getch(); break; case '4':system("cls"); printf("计算器已关闭,按任意键退出 :)\n"); exit(0); } }
简要说明
- 输入第一个稀疏矩阵的行数,列数,非零个数
- 依次输入非零数所在的具体坐标
- 同理 输入第二个稀疏矩阵的行列非零个数
- 通常以回车作为输入结束
- 计算结果以矩阵的形式表现出来
总结
总通过本次实验,在我的学习理解上有很大的促进作用。单单对稀疏矩阵,我了解了由于矩阵在程序中常使用二维阵列表示,二维阵列的大小稀疏矩阵与使用的存储器空间成正比,如果多数的元素没有数据,则会造成存储器空间的浪费,为此,必须设计稀疏矩阵的阵列储存方式,利用较少的存储器空间储存完整的矩阵数据。二维数组Amn中有N个非零元素,若N<<m*n,则称A为稀疏矩阵。由于稀疏矩阵中含有很多的0元素,在计算机中存储会浪费很多的空间,因此我们通常采用压缩存储的方法。
-
数据结构C语言之稀疏矩阵的加法
2010-11-19 21:01:141、进行加法运算的两个矩阵由用户输入。并且用三元组顺序表表示。 2、程序首先判断两个矩阵是否能够相加。若能,在进行运算后在屏幕上现实结果,否则给出相应信息。 -
课程设计:用C语言编纂的稀疏矩阵运算器(加、减、乘、求逆)
2021-05-20 16:40:57课程设计:用C语言编写的稀疏矩阵运算器(加、减、乘、求逆)#include#includeint system(const char *string);#define maxsize 2000typedef struct{int row;int col;int data;}triple;typedef struct{triple data...课程设计:用C语言编写的稀疏矩阵运算器(加、减、乘、求逆)
#include
#include
int system(const char *string);
#define maxsize 2000
typedef struct
{
int row;
int col;
int data;
}triple;
typedef struct
{
triple data[maxsize];
int m,n,len;
}matrix;
typedef struct
{
int row;
int col;
float data;
}triple_f;
typedef struct
{
triple_f data[maxsize];
int m,n,len;
}matrix_f;
matrix_f *Init_f()
{
int i=0;
matrix_f *A;
A=(matrix_f*)malloc(sizeof(matrix_f));
A->len=0;
A->m=0;
A->n=0;
for(i=0;i
{
A->data[i].col=0;
A->data[i].row=0;
A->data[i].data=0;
}
return A;
}
matrix *Init()
{
int j=0;
matrix *A;
A=(matrix*)malloc(sizeof(matrix));
A->len=0;
A->m=0;
A->n=0;
for(j=0;j
{
A->data[j].col=0;
A->data[j].row=0;
A->data[j].data=0;
}
return A;
}
void print_menu()
{
char ch1='=';
int i;
for(i=0;i<80;i++)
printf("%c",ch1);
}
void qiuni(matrix_f *A,matrix_f **C)
{
/*参数声明*/
int i=0,j=0,m=0,row=0,col=0,r1,k,tz=0,tem_row,tem_col,l;
float n1,n2,t,x,n3,sum;
matrix_f *B;
/*变量运算*/
B=Init_f();
/*创建矩阵AI*//*这部分已完成,下面部分禁止修改*/
m=0;j=0;
B->m=A->m; B->n=2*(A->n); B->len=(B->m)*(B->n);
tem_row=0; tem_col=0;
for(i=0;ilen;i++)
{
B->data[i].data=0;
B->data[i].col=tem_col;
B->data[i].row=tem_row;
tem_col++;
if(tem_col==B->n)
{
tem_col=0;
tem_row++;
}
}
for(i=0;ilen;i++)
for(j=0;jlen;j++)
if(B->data[j].row==A->data[i].row&&B->data[j].col==A->data[i].col)
B->data[j].data=A->data[i].data;
j=0;
for(i=0;im;i++)
{
B->data[j*(B->n)+i+B->m].data=1;
j++;
}
/*变换矩阵AI*/
row=0;col=0;i=0;j=0;n1=1.0;n2=1.0;
r1=0;k=0;t=1.0; l=0;x=0;
for(col=0;colm;col++)
{
for(row=0;rowm;row++)
{
if(row!=col)
{
for(i=0;ilen;i++)
if(B->data[i].row==row&&B->data[i].col==col)
{n1=B->data[i].data;break;}
for(j=0;jlen;j++)
if(B->data[j].row==col&&B->data[j].col==col)
{n2=B->data[j].data;break;}
t=n1/n2;
for(r1=0;r1m);r1++)
{
for(k=0;klen;k++)
if(B->data[k].row==col&&B->data[k].col==r1)
{n3=B->data[k].data;break;}
x=n3*t;
for(l=0;llen;l++)
if(B->data[l].row==row&&B->data[l].col==r1)
{B->data[l].data=B->data[l].data-x;break;}
}
}
}
}
row=0;j=0;n1=0;col=0;i=0;
for(row=0;rowm;row++)
{
for(j=0;jlen;j++)
if(B->data[j].row==row&&B->data[j].col==row)
{n1=B->data[j].data;break;}
for(col=0;coln;col++)
for(i=0;ilen;i++)
if(B->data[i].row==row&&B->data[i].col==col)
{B->data[i].data=(B->data[i].data)/n1;break;}
}
row=0;col=0;sum=1;tem_row=0;tem_col=0;
for(row=0;rowm;row++)
{
for(i=0;ilen;i++)
{
if(B->data[i].row==row&&B->data[i].col==row)
sum=sum*(B->data[i].data);
}
}
if(sum==0)
printf("您所输入的矩阵没有逆矩阵!\n");
else
{
(*C)->len=B->len/2;
(*C)->m=B->m;
(*C)->n=B->m;
for(i=0;ilen;i++)
{
(*C)->data[i].data=B->data[i+(tem_row+1)*B->m].data;
(*C)->data[i].row=B->data[i+(tem_row+1)*B->m].row;
(*C)->data[i].col=B->data[i+(tem_row+1)*B->m].col;
tem_col++;
if(tem_col==(*C)->m)
{
tem_col=0;
tem_row++;
}
}
}
}
void print_menu2()
{
print_menu();
printf("= 1.创建矩阵A =");
printf("= 2.创建矩阵B =");
printf("= 3.创建矩阵C【求逆矩阵专用】 =");
printf("= 4.矩阵A + 矩阵B =");
printf("= 5.矩阵A - 矩阵B =");
printf("= 6.矩阵A * 矩阵B =");
printf("= 7.求矩阵A的逆矩阵 =");
printf("= 8.退出 =");
print_menu();
printf("请选择要进行的操作:");
}
void Creat(matrix **A)
{
int i=0;
int n1,n2;
int j=0;
FILE *get;
char getname[20];
int m=0;
int row=0;
int col=0;
FILE *in1;
char ch1;
int g=0;
FILE *in2;
char ch2;
int p=0;
int z=0;
print_menu();
printf("= 1.手动创建 =");
printf("= 2.从文件载入 =");
print_menu();
printf("请选择矩阵创建方式:");
scanf("%d",&j);
switch(j)
{
case 1:
{system("cls");
printf("=========================请输入矩阵的行列数及非零元个数=========================");
scanf("%d%d%d",&(*A)->m,&(*A)->n,&(*A)->len);
for(i=0;ilen;i++)
{
printf("请输入第 %d 个非零元素的行: ",i+1);
scanf("%d",&n1);
(*A)->data[i].row=(n1-1);
printf("请输入第 %d 个非零元素的列: ",i+1);
scanf("%d",&n2);
(*A)->data[i].col=(n2-1);
printf("请输入第 %d 个非零元素的值: ",i+1);
scanf("%d",&(*A)->data[i].data);
printf("\n");
}
printf("==================================矩阵创建完成==================================");
break;
}
case 2:
{
system("cls");
printf("==============================请输入要打开的文件名==============================");
printf(" ");
scanf("%s",&getname);
if((get=fopen(getname,"r"))==NULL)
{
printf("打开文件出错!请检查文件是否存在。\n");
system("pause");
exit(0);
}
else
printf("打开完成!\n");
printf("正在从文件中载入矩阵...\n");
in1=fopen(getname,"r");
while(!feof(in1))
{
ch1=fgetc(in1);
if(ch1=='\n')
g++;
}
in2=fopen(getname,"r");
while(!feof(in2))
{
ch2=fgetc(in2);
if(ch2==' ')
p++;
else if(ch2=='\n')
break;
}
p=p+1; g=g+1;
printf("矩阵载入成功!\n");
printf("\n文本行数为:%d\n",g);
printf("文本列数为:%d\n",p);
printf("非零元素信息如下:\n");
while(!feof(get))
{
fscanf(get,"%d",&n1);
if(n1!=0)
{
(*A)->data[m].data=n1;
(*A)->data[m].row=row;
(*A)->data[m].col=col;
printf("行:%d ",(*A)->data[m].row+1);
printf("列:%d ",(*A)->data[m].col+1);
printf("值:%d \n",(*A)->data[m].data);
m++;
col++;
z++;
if(col==p)
{col=0; row++;}
}
else if(n1==0)
{
col++;
if(col==p)
{col=0;row++;}
}
}
(*A)->m=g;
(*A)->n=p;
(*A)->len=z;
}
}
}
void print(matrix *A)
{
FILE *put;
char putname[20];
int i=0;
int row;
int col;
int j;
char ch1='0';
char ch2=' ';
printf("是否将结果显示在屏幕上?(建议大矩阵保存在文件中。)\t是[0]/否[1]\n");
scanf("%d",&j);
switch(j)
{
case 0:
{system("cls");
for(row=0;rowm;row++)
{
for(col=0;coln);col++)
{
if(A->data[i].col==col&&A->data[i].row==row)
{
printf("%d ",A->data[i].data);
i++;
}
else printf("0 ");
}
printf("\n");
}
break;
}
case 1:
{
system("cls");
printf("请输入要保存的文件名:");
scanf("%s",&putname);
/*写入文件部分*/
if((put=fopen(putname,"w"))==NULL)
{
printf("无法打开!");
exit(0);
}
else
printf("\a创建或打开文件 %s 成功!\n",putname);
{
for(row=0;rowm;row++)
{
for(col=0;coln;col++)
{
if(A->data[i].col==col&&A->data[i].row==row)
{fprintf(put,"%d",A->data[i].data);fputc(ch2,put);i++;}
else {fputc(ch1,put);fputc(ch2,put);}
}
fputc(10,put);
}
}
fclose(put);
printf("已保存!\n");
break;
}
}
}
int value(matrix *a,int i,int j) //矩阵相乘时 取出一行或一列
{
int k=0;
while(klen)&&(a->data[k].row!=i||a->data[k].col!=j))
k++;
if(klen)
return a->data[k].data;
else
return 0;
}
void arr(matrix *a,matrix *b,matrix **c)
{
int i=0,j=0,k=0,p=0;
int tem;
if(a->m!=b->n)
{
printf("您输入的两个矩阵不满足相乘条件!");
system("pause");
exit(0);
}
for(i=0;in;i++)
{
for(j=0;jm;j++)
{
tem=0;
for(k=0;km;k++)
{
tem=tem+value(a,i,k)*value(b,k,j);
}
if(tem!=0)
{
(*c)->data[p].row=i;
(*c)->data[p].col=j;
(*c)->data[p].data=tem;
p++;
}
}
(*c)->n=a->n;
(*c)->m=a->m;
(*c)->len=p;
}
}
void add(matrix *a,matrix *b,matrix **c)
{
if(a->m==b->m&&a->n==b->n)
{
int i=0,j=0,k=0;
(*c)->m=a->m;
(*c)->n=a->n;
while(ilen||jlen)
{
if(i==a->len&&jlen)
{
(*c)->data[k].col=b->data[j].col;
(*c)->data[k].row=b->data[j].row;
(*c)->data[k++].data=b->data[j].data;
(*c)->len++;
j++;
}
else if(ilen&&j==b->len)
{
(*c)->data[k].col=a->data[i].col;
(*c)->data[k].row=a->data[i].row;
(*c)->data[k++].data=a->data[i].data;
(*c)->len++;
i++;
}
else
{
if(a->data[i].row>b->data[j].row)
{
(*c)->data[k].col=b->data[j].col;
(*c)->data[k].row=b->data[j].row;
(*c)->data[k++].data=b->data[j].data;
(*c)->len++;
j++;
}
else if(a->data[i].rowdata[j].row)
{
(*c)->data[k].col=a->data[i].col;
(*c)->data[k].row=a->data[i].row;
(*c)->data[k++].data=a->data[i].data;
(*c)->len++;
i++;
}
else
{
if(a->data[i].col==b->data[j].col)
{
if(a->data[i].data+b->data[j].data!=0)
{
(*c)->data[k].col=a->data[i].col;
(*c)->data[k].row=a->data[i].row;
(*c)->data[k++].data=a->data[i].data+b->data[j].data;
(*c)->len++;
}
i++;
j++;
}
else if(a->data[i].col>b->data[j].col)
{
(*c)->data[k].col=b->data[j].col;
(*c)->data[k].row=b->data[j].row;
(*c)->data[k++].data=b->data[j].data;
(*c)->len++;
j++;
}
else if(a->data[i].coldata[j].col)
{
(*c)->data[k].col=a->data[i].col;
(*c)->data[k].row=a->data[i].row;
(*c)->data[k++].data=a->data[i].data;
(*c)->len++;
i++;
}
}
}
}
}
else
{
printf("您输入的两个矩阵不满足运算条件!\n");
system("pause");
}
}
void sub(matrix *A,matrix *B,matrix **C)
{
int k=0;
for(k=0;klen;k++) B->data[k].data=-B->data[k].data;
if(A->m==B->m&&A->n==B->n) add(A,B,C);
else
{
for(k=0;klen;k++)
B->data[k].data=-B->data[k].data;
system("pause");
}
}
void Creat_f(matrix_f **A)
{
int i=0;
float n1;
int n3,n4;
int j=0;
FILE *get;
char getname[20];
int m=0;
int row=0;
int col=0;
FILE *in1;
char ch1;
int g=0;
FILE *in2;
char ch2;
int p=0;
int z=0;
print_menu();
printf("= 1.手动创建 =");
printf("= 2.从文件载入 =");
print_menu();
printf("请选择矩阵创建方式:");
scanf("%d",&j);
switch(j)
{
case 1:
{system("cls");
printf("=========================请输入矩阵的行列数及非零元个数=========================");
scanf("%d%d%d",&(*A)->m,&(*A)->n,&(*A)->len);
for(i=0;ilen;i++)
{
printf("请输入第 %d 个非零元素的行: ",i+1);
scanf("%d",&n3);
(*A)->data[i].row=(n3-1);
printf("请输入第 %d 个非零元素的列: ",i+1);
scanf("%d",&n4);
(*A)->data[i].col=(n4-1);
printf("请输入第 %d 个非零元素的值: ",i+1);
scanf("%f",&(*A)->data[i].data);
printf("\n");
}
printf("==================================矩阵创建完成==================================");
break;
}
case 2:
{
system("cls");
printf("==============================请输入要打开的文件名==============================");
printf(" ");
scanf("%s",&getname);
if((get=fopen(getname,"r"))==NULL)
{
printf("打开文件出错!请检查文件是否存在。\n");
system("pause");
exit(0);
}
else
printf("打开完成!\n");
printf("正在从文件中载入矩阵...\n");
in1=fopen(getname,"r");
while(!feof(in1))
{
ch1=fgetc(in1);
if(ch1=='\n')
g++;
}
in2=fopen(getname,"r");
while(!feof(in2))
{
ch2=fgetc(in2);
if(ch2==' ')
p++;
else if(ch2=='\n')
break;
}
p=p+1; g=g+1;
printf("矩阵载入成功!\n");
printf("\n文本行数为:%d\n",g);
printf("文本列数为:%d\n",p);
printf("非零元素信息如下:\n");
while(!feof(get))
{
fscanf(get,"%f",&n1);
if(n1!=0)
{
(*A)->data[m].data=n1;
(*A)->data[m].row=row;
(*A)->data[m].col=col;
printf("行:%d ",(*A)->data[m].row+1);
printf("列:%d ",(*A)->data[m].col+1);
printf("值:%0.1f \n",(*A)->data[m].data); //检测载入是否成功。
m++;
col++;
z++;
if(col==p)
{col=0; row++;}
}
else if(n1==0)
{
col++;
if(col==p)
{col=0;row++;}
}
}
(*A)->m=g;
(*A)->n=p;
(*A)->len=z;
}
}
}
void print_f(matrix_f *A)
{
FILE *put;
char putname[20];
int i=0;
int j;
char ch1='0';
char ch2=' ';
int t_row=0,t_col=0;
printf("是否将结果显示在屏幕上?(建议大矩阵保存在文件中。)\t是[0]/否[1]\n");
scanf("%d",&j);
switch(j)
{
case 0:
{system("cls");
for(i=0;ilen;i++)
{
printf("%0.1f ",A->data[i].data);
t_col++;
if(t_col==A->n)
{
printf("\n");
t_col=0;
}
}
break;
}
case 1:
{
system("cls");
printf("请输入要保存的文件名:");
scanf("%s",&putname);
/*写入文件部分*/
if((put=fopen(putname,"w"))==NULL)
{
printf("无法打开!");
exit(0);
}
else
printf("\a创建或打开文件 %s 成功!\n",putname);
{
for(i=0;ilen;i++)
{
fprintf(put,"%0.1f",A->data[i].data);
fputc(ch2,put);fputc(ch2,put);fputc(ch2,put);
t_col++;
if(t_col==A->n)
{
fputc(10,put);
t_col=0;
}
}
}
fclose(put);
printf("已保存!\n");
break;
}
}
}
void main()
{
int num;
matrix *A;
matrix *B;
matrix *C;
matrix_f *S;
matrix_f *T;
A=Init();
B=Init();
C=Init();
S=Init_f();
T=Init_f();
print_menu2();
scanf("%d",&num);
while(num<=8)
{
switch(num)
{
case 1:
{
system("cls");
printf("创建矩阵A...\n");
Creat(&A);
system("pause");
system("cls");
print_menu2();
break;
}
case 2:
{
system("cls");
printf("创建矩阵B...\n");
Creat(&B);
system("pause");
system("cls");
print_menu2();
break;
}
case 3:
{
system("cls");
printf("创建矩阵S...\n");
Creat_f(&S);
system("pause");
system("cls");
print_menu2();
break;
}
case 4:
{
printf("正在执行加法运算...\n");
add(A,B,&C);
print(C);
system("pause");
system("cls");
print_menu2();
break;
}
case 5:
{
printf("正在执行减法运算...\n");
sub(A,B,&C);
print(C);
system("pause");
system("cls");
print_menu2();
break;
}
case 6:
{
printf("正在执行乘法运算...\n");
arr(A,B,&C);
print(C);
system("pause");
system("cls");
print_menu2();
break;
}
case 7:
{
if(A->m!=A->n)
printf("矩阵行数不等于列数,没有逆矩阵!\n");
else
{
printf("正在执行求逆运算...\n");
qiuni(S,&T);
print_f(T);
system("pause");
system("cls");
print_menu2();
}
break;
}
case 8:
{
exit( 0);
break;
}
}//switch结束
scanf("%d",&num);
}//while结束
scanf("%d",&num);
}
-
C语言实现稀疏矩阵运算,求解线性方程组问题(基于eigen)
2021-12-03 15:18:50近期导师让我将一个matlab代码改写成C,其中涉及到大量的矩阵运算和稀疏矩阵运算,经过一段时间的摸索和实践,记录一下这段时间的学习经验 首先由于要基于C语言实现一些矩阵的运算,加减乘除,求逆,以及解线性方程... -
(数据结构课程设计)稀疏矩阵运算器
2017-11-03 19:45:00实现一个能进行稀疏矩阵基本运算的运算器。 具体功能有: (1)以“带行逻辑链接信息”的三元组顺序表示稀疏矩阵,实现两个稀疏矩阵相加、相减、相乘、求逆以及矩阵转置和求矩阵对应行列式值的功能。 (2)稀疏矩阵... -
矩阵压缩存储之稀疏矩阵详解(C语言版)
2021-04-04 23:44:04矩阵压缩存储之稀疏矩阵详解(C语言版) -
稀疏矩阵运算器 数据结构
2010-04-18 19:02:58数据结构(C语言版)实习4.1,稀疏矩阵运算器 -
C++稀疏矩阵的各种基本运算并实现加法乘法
2021-05-19 12:33:37代码:#include #include#includeusing namespace std;#define M 4#define N 4#define MaxSize 100typedef int ElemType;typedef struct{int r;int c;ElemType d;///元素值} TupNode; ///三元组定义typedef struct{... -
数据结构课程设计--稀疏矩阵的存储及运算.doc
2021-05-22 15:08:35稀疏矩阵的存储及运算一 目的通过课程设计,巩固和加深理论知识掌握问题分析方法包括问题描述分析、设计、实现、结果分析struct Triple{ int i,j; //行下标和列下标ElemType e; //非零元素值};struct RLSMatrix{ ... -
数据结构稀疏矩阵基本运算实验报告..doc
2021-05-21 16:36:50课 程 设 计课程:数据结构题目:稀疏矩阵4 三元组单链表 结构体(行数、列数、头) 矩阵运算重载运算符 优班级:姓名:学号:设计时间:2010年1月17日——2010年5月XX日成绩:指导教师:楼建华一、题目题目稀疏矩阵4... -
《数据结构 课程设计》稀疏矩阵实验报告.doc
2021-05-21 16:35:47系统分析1三、 概要设计1(1)主界面的设计:2(2)系数矩阵的存储2(3)具体实现流程图:3四、详细设计4(2)稀疏矩阵的相加:5五、 运行与测试8六、 总结与心得8参考文献9源代码9一、概述稀疏矩阵的加法运算,既将稀疏矩阵A... -
数据结构(C语言)- 稀疏矩阵的快速乘法
2020-01-21 20:01:08稀疏矩阵的结构定义 typedef struct { int i, j; //该非零元的行下标和列下标 ElemType e; //非零元对应的值 }Triple; typedef struct { Triple data[MAX_SIZE]; //非零元三元组表 int... -
4.1题稀疏矩阵运算器.doc
2021-05-21 07:23:014.1题稀疏矩阵运算器.doc4.1题 稀疏矩阵运算器需求分析1.以“带行逻辑链接信息”的三元组数许表表示稀疏矩阵。2.能实现对两个矩阵相加,相减和相乘的运算。3.输入形式采用三元组表示,而运算结果的矩阵则以通常的... -
课程设计:用C语言编写的稀疏矩阵运算器(加、减、乘、求逆)
2013-09-25 20:43:16课程设计:用C语言编写的稀疏矩阵运算器,可对超过1000行的大矩阵执行加、减、乘、求逆运算。 -
数据结构课程设计《稀疏矩阵运算器》
2015-01-04 09:44:00最近正在弄数据结构课程设计内容,说实话,感觉自己数据结构学的就是渣,好多东西都不会。还是要多学点东西啊。现在暂且贴点之前写完的东西吧,...实现一个能进行稀疏矩阵基本运算的运算器。 1.2 基本要求 以“带... -
稀疏矩阵的加,减,乘,转置
2017-05-19 10:14:00实现一个能进行稀疏矩阵基本运算的运算器。 以“带行逻辑链接信息”的三元组标表示稀疏矩阵,实现矩阵的转置,实现两个矩阵相加,相减和相乘的运算。稀疏矩阵的输入形势采用三元组表示,而运算结果的矩阵则以通常的... -
数据结构--稀疏矩阵转置(列序递增算法)的c语言实现(超详细注释/实验报告)
2021-10-24 23:39:57稀疏矩阵是指矩阵中大多数元素为零的矩阵。从直观上讲,当非零元素个数低于总元素的30%时,这样的矩阵为稀疏矩阵。