/*
矩阵乘法
逻辑关系较强,需要细细体会
*/
#include <iostream>
using namespace std;
#define MAX 100
#define HMAX 100
typedef struct node{
int x,y;
int value;
}SRC;
typedef struct node_1{
SRC arr[MAX];
int cols[HMAX]; /*矩阵中的每一行的第一个非零元素在三元组中的位置*/
int mu,nu,tu; /*分别表示矩阵的行数 列数和总的非零元素的数目*/
}SRCD;
void Create(int a[][4],int m,int n,SRCD* &srcd)
{
/*遍历矩阵 构造三元组 同时存储相应的矩阵的每一行的相应的第一个非零元素在三元组中的位置*/
if(a== NULL) return ;
int k=0;
int flag ;
srcd->tu =0 ;
for(int i=1;i<=m;i++){
flag = 0;
srcd->cols[i]=0;
for(int j=1;j<=n;j++){
if(a[i][j]){
k++;
if(flag == 0){
srcd->cols[i] = k;
flag =1;
}
srcd->arr[k].x = i;
srcd->arr[k].y = j;
srcd->arr[k].value = a[i][j];
srcd->tu++;
}
}
}
cout<<sizeof(srcd->cols)/sizeof(int)<<endl;
srcd->mu = m;
srcd->nu = n;
}
void DisplaySrcd(SRCD* srcd)
{
/*遍历三元组 显示三元组中的每一个三语组的x y value*/
if (srcd == NULL) return ;
for(int i=1;i<=srcd->tu;i++){
cout<<srcd->arr[i].x<<" "<<srcd->arr[i].y<<" "<< srcd->arr[i].value<<endl;
}
}
void Deal(SRCD* srcd_1,SRCD* srcd_2,SRCD* &dest)
{
/*求解矩阵的乘法*/
if( srcd_1 == NULL || srcd_2 == NULL ) return ;
if( srcd_1->nu != srcd_2->mu ) return ;
if( srcd_1->tu * srcd_2->tu ){
dest->mu = srcd_1->mu;
dest->nu = srcd_2->nu;
dest->tu = 0;
int* temp = new int[srcd_2->nu+1];
int tp;
int h;
int s_l;
int t;
int col;
for( int i=1;i<=srcd_1->mu;i++){ /*遍历被乘矩阵的每一行*/
for( int j=1;j<=srcd_2->nu;j++){ /*初始化结矩阵的每一行的每一个元素的值*/
temp[j]=0;
}
dest->cols[i] = dest->tu+1;
if( i<srcd_1->mu ) tp = srcd_1->cols[i+1]; /*找到被乘矩阵的每一行的遍历上边界*/
else{
tp = srcd_1->tu+1; /*当被乘矩阵到达最后的时候将遍历的商界设为被乘矩阵的最大三语组的数目加一 从而得到被乘矩阵的最后一行的遍历的上界*/
}
for( int k=srcd_1->cols[i];k<tp;k++ ){ /*去的被乘矩阵的每一行的第一个非零三元组开始位置 也就是找到北城矩阵的每一行便利的下边界*/
s_l = srcd_1->arr[k].y;
if( s_l < srcd_2->mu ) t = srcd_2->cols[s_l+1]; /*根据北城矩阵相应的每一行的每一个非零元素从而确定相应的行 这就是陈矩阵的下边界*/
else{
t = srcd_2->tu+1; /*确定成矩阵的相应行的上边界*/
}
for(int h = srcd_2->cols[s_l];h<t;h++){ /*根据成矩阵的遍历边界进行相应的遍历 求得结果矩阵的第i行的每一个节点的结果*/
col = srcd_2->arr[h].y;
temp[col] += srcd_1->arr[k].value * srcd_2->arr[h].value;
}
}
for( int j = 1;j <= dest->nu;j++){ /*使用三元组存储结果矩阵相应的行的每一个非零元 不难发现最终的结果矩阵的行受到被乘矩阵的影响 然而列受到相应的乘矩阵的影响 这也正是矩阵的乘法的原理*/
if(temp[j]){
dest->tu++;
dest->arr[dest->tu].x = i;
dest->arr[dest->tu].y = j;
dest->arr[dest->tu].value = temp[j];
}
}
}
}
}
int main()
{
int a[4][4], b[4][4];
for(int i=1;i<=3;i++){
for(int j=1;j<=3;j++)
cin>>a[i][j];
}
for(int i=1;i<=3;i++){
for(int j=1;j<=3;j++)
cin>>b[i][j];
}
SRCD *srcd_1 = NULL ,*srcd_2 = NULL,*dest = NULL;
srcd_1= new SRCD;
srcd_2= new SRCD;
dest = new SRCD;
Create(a,3,3,srcd_1); /*创建被乘矩三元组*/
cout<<srcd_1->tu<<endl;
Create(b,3,3,srcd_2); /*创建乘矩阵三元组*/
cout<<srcd_2->tu<<endl;
DisplaySrcd(srcd_1); /*遍历被乘矩阵三元组*/
cout<<"-------------------------我是分割线-----------------------"<<endl;
DisplaySrcd(srcd_2); /*遍历乘矩阵三元组*/
cout<<"-------------------------我是分割线-----------------------"<<endl;
Deal(srcd_1,srcd_2,dest); /*求解矩阵的乘法*/
DisplaySrcd(dest); /*遍历最终的结果矩阵的三元组*/
system("pause");
return 0;
}