三元组矩阵的乘法


三元组矩阵的乘法,针对稀疏矩阵:

源代码如下:

<构造位置表用了两种方法>

#include <stdlib.h>
#include <stdio.h>
#define MAXSIZE 100	//非零元的最大个数
#define MAX_ROW_NUM 20//最大行列数
#define ElenType int
#define Status int//返回值类型
#define OK 1
#define ERROR 0
#define OVERFLOW -1

/*稀疏矩阵的三元组存储结构*/
typedef struct {
	int row,col;//非零元的行下标和列下标
	ElenType data;//元素的值
}Triple;
typedef struct {
	Triple dataArray[MAXSIZE+1];//非零元组表,dataArray[0]未用
	int rpos[MAX_ROW_NUM+1];//各行第一个非零元的位置(在目标矩阵中的存储位置)表
	int row_count,col_count,data_count;//矩阵的行数,列数和非零元个数
}*TSMatrix,Matrix;//代表Triple Sequence Matrix 三元组矩阵

/*创建一个矩阵*/
Status CreateTSMatrix(TSMatrix &M){
	M = (TSMatrix)malloc(sizeof(Matrix));
	if(!M){
		exit(OVERFLOW);
	}
	printf("输入三元组的行数,列数和非零元个数:");
	int rc,cc,dc;
	scanf("%d%d%d",&rc,&cc,&dc);
	M->row_count = rc;
	M->col_count = cc;
	M->data_count = dc;
	int i = 0;
	printf("开始构造矩阵\n");
	int r,c,d;//作为临时变量
	while(i<dc){
		printf("输入第%d个非零元的行号,列号和值:",i+1);
		scanf("%d%d%d",&r,&c,&d);
		if(r>rc || c>cc){	//行和列不能越界
			printf("此组数据不合法,请重新输入\n");
			continue;
		}else{
			//因为下标从1 开始,所以i+1
			M->dataArray[i+1].row = r;
			M->dataArray[i+1].col = c;
			M->dataArray[i+1].data = d;
			i++;//此时才++
		}
	}
	/*构造rpos[]的值*/
	//方法一//
	/*此方法就是只用一个数组rpos本身来构造*/
	for(i=1;i<=M->row_count;i++){
		M->rpos[i] = 0;//赋初值为0
	}
	for(i=1;i<=M->data_count;i++){
		M->rpos[M->dataArray[i].row]++;//计算每一行有多少个非零元
	}
	//从后往前计算rpos[]的值,即累加
	for(i=M->row_count;i>=1;i--){
		M->rpos[i] = 1;
		for(int j=i-1;j>=1;j--){
			M->rpos[i] += M->rpos[j];
		}
	}
	/方法二//
	/*用一个辅助数组num来计算非零元个数,与稀疏矩阵的转置里方法一致*/
/*	int i=1,num[MAX_ROW_NUM+1];
	for(i=1;i<=M->row_count;i++){
		M->rpos[i] = 0;//赋初值为0
	}
	for(i=1;i<=M->data_count;i++){
		num[M->dataArray[i].row]++;//计算每一行有多少个非零元
	}
	M->rpos[1] = 1;
	for(i=2;i<=M->row_count;i++){
		M->rpos[i] = M->rpos[i-1] + num[i];//递推
	}
*/
	printf("构造矩阵成功\n");
	return OK;
}
/*打印三元组矩阵*/
Status PrintTSMatrix(TSMatrix M){
	//用描述法吧
	for(int i=1;i<=M->data_count;i++){
		printf("行号 列号 值:%d %d %d",M->dataArray[i].row,M->dataArray[i].col, M->dataArray[i].data);
		printf("\n");
	}
	return OK;
}
/*实现矩阵的乘法: Q = M * N */
Status MultTSMatrix(TSMatrix M,TSMatrix N,TSMatrix &Q){
	int arow,brow,p,q,ccol,ctemp[MAX_ROW_NUM+1],t,tp;
	if(M->col_count != N->row_count){//不能相乘
		return ERROR;
	}
	if(0 == M->data_count * N->data_count ){//有一个是零矩阵
		return ERROR;
	}
	//Q初始化
	Q->row_count = M->row_count;
	Q->col_count = N->col_count;
	Q->data_count = 0;
	//从M的第一行开始到最后一行,arow是M的当前行
	for(arow=1;arow<=M->row_count;arow++){
		for(ccol=1;ccol<=Q->col_count;ccol++){
			ctemp[ccol] = 0;//Q的当前行的各列元素清零
		}
		Q->rpos[arow] = Q->data_count + 1;//开始时从第一个存储位置开始存,后面是基于前面的
		if(arow < M->row_count){
			tp = M->rpos[arow+1];//下一行的起始位置
		}else{
			tp = M->data_count + 1;//最后一行的边界
		}
		for(p=M->rpos[arow];p<tp;p++){
			//对M当前行的每一个非零元
			//找到对应元素在N中的行号,即M中当前元的列号
			brow = M->dataArray[p].col;
			//原理同上
			if(brow<N->row_count){
				t = N->rpos[brow+1];
			}else{
				t = N->data_count+1;
			}
			for(q=N->rpos[brow];q<t;q++){
				ccol = N->dataArray[q].col;//乘积元素在Q中列的位置
				ctemp[ccol] += M->dataArray[p].data * N->dataArray[q].data;
			}//for_q
		}//for_p
		//该压缩存储该行非零元了
		for(ccol=1;ccol<=Q->col_count;ccol++){
			if(0!=ctemp[ccol]){
				if(++Q->data_count > MAXSIZE){//注意这里有个++
					return ERROR;
				}
				Q->dataArray[Q->data_count].row = arow;
				Q->dataArray[Q->data_count].col = ccol;
				Q->dataArray[Q->data_count].data = ctemp[ccol];
			}
		}
	}//for_arow
	return OK;
}
int main(){
	TSMatrix M,N,Q;
	Q = (TSMatrix)malloc(sizeof(TSMatrix));
	CreateTSMatrix(M);
	printf("矩阵M:\n");
	PrintTSMatrix(M);
	CreateTSMatrix(N);
	printf("矩阵N:\n");
	PrintTSMatrix(N);
	MultTSMatrix(M,N,Q);
	printf("矩阵Q:\n");
	PrintTSMatrix(Q);
	return 0;
}


现在用一个例子来验证一下:


运行结果:



  • 10
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值