这道题也是上周就写了的,今天晚上赶紧发出来。题目如下:
看一下题目,就是三元组表稀疏矩阵的乘法,然后输出。
首先将矩阵每行的非0元个数记下来,那么矩阵每行第一个非0元在三元表的位置就是上一行非0元个数加上上一行首个非0元位置之和。这样就可以不用遍历三元表,就可以快速找到相应的三元组表元素。相乘时先将结果存入一个数组中,然后取其中非0元素存入新的三元组表。最后输出新三元组表即可。示例如下:
以下是我的实现:
#include <stdio.h>
#include <stdlib.h>
struct Triple
{
int ti;
int tj;
int value;
};
struct tripleList
{
struct Triple T[2000];
int li;
int lj;
int ln;
};
void createNewTripleList (struct tripleList *list);
void getRowPot (struct tripleList *list,int rowPot[]);
void clear (struct tripleList *list);
void printTripleList (struct tripleList *list);
void mul (struct tripleList *list1,struct tripleList *list2,struct tripleList *list3,int rowPot1[],int rowPot2[]);
void run ();
int main()
{
run ();
return 0;
}
void run ()
{
int rowPot1[2000]={0},rowPot2[2000]={0};
struct tripleList list1,list2,list3;
createNewTripleList (&list1);
createNewTripleList (&list2);
getRowPot (&list1,rowPot1);
getRowPot (&list2,rowPot2);
mul (&list1,&list2,&list3,rowPot1,rowPot2);
printTripleList (&list3);
}
void createNewTripleList (struct tripleList *list)
{
int i=0,a,b,c;
scanf ("%d%d",&(list->li),&(list->lj));
while (1)
{
scanf ("%d%d%d",&a,&b,&c);
if (a==0&&b==0&&c==0)
{
break;
}
list->T[i].ti=a-1;
list->T[i].tj=b-1;
list->T[i].value=c;
i++;
}
list->ln=i;
}
void getRowPot (struct tripleList *list,int rowPot[])
{
int n[2000]={0};
int i,pre1=0,pre2=0;
for (i=0;i<=list->ln-1;i++)
{
(n[list->T[i].ti])++;
}
for (i=0;i<=list->li;i++)
{
rowPot[i]=pre1+pre2;
pre1=n[i];
pre2=rowPot[i];
}
}
void printTripleList (struct tripleList *list)
{
int i;
for (i=0;i<=list->ln-1;i++)
{
printf ("%d %d %d\n",list->T[i].ti+1,list->T[i].tj+1,list->T[i].value);
}
}
void mul (struct tripleList *list1,struct tripleList *list2,struct tripleList *list3,int rowPot1[],int rowPot2[])
{
int i,j,k,l,no,max,n,len1,len2,A[2000]={0};
list3->li=list1->li;
list3->lj=list2->lj;
for (i=0,n=0;i<=list1->li-1;i++)
{
len1=rowPot1[i+1]-1;
for (j=rowPot1[i],max=0;j<=len1;j++)
{
len2=rowPot2[list1->T[j].tj+1]-1;
for (k=rowPot2[list1->T[j].tj];k<=len2;k++)
{
no=list2->T[k].tj;
A[no]+=list1->T[j].value*list2->T[k].value;
max=no>max?no:max;
}
}
for (l=0;l<=max;l++)
{
if (A[l]!=0)
{
list3->T[n].ti=list1->T[j-1].ti;
list3->T[n].tj=l;
list3->T[n].value=A[l];
++n;
A[l]=0;
}
}
}
list3->ln=n;
}
以下是各函数的注释:
void createNewTripleList (struct tripleList *list)
{
int i=0,a,b,c;
scanf ("%d%d",&(list->li),&(list->lj));//输入行数列数
while (1)
{
scanf ("%d%d%d",&a,&b,&c);//输入行 列 数据
if (a==0&&b==0&&c==0)//都为0时停止输入
{
break;
}
list->T[i].ti=a-1;//赋值,因为题目输入的行列数据是从1开始的,这里将它转为以0开始,最后输出时在加上1
list->T[i].tj=b-1;
list->T[i].value=c;
i++;
}
list->ln=i;//得到三元组表元素个数
}
void getRowPot (struct tripleList *list,int rowPot[])
{
int n[2000]={0};
int i,pre1=0,pre2=0;
for (i=0;i<=list->ln-1;i++)//得到矩阵每行的非0元个数
{
(n[list->T[i].ti])++;
}
for (i=0;i<=list->li;i++)
{
rowPot[i]=pre1+pre2;//本行第一个非0元素在三元组表中的位置,上一行的非0元个数加上上一行第一个非0元在三元组表中的位置
pre1=n[i];
pre2=rowPot[i];
}
}
void mul (struct tripleList *list1,struct tripleList *list2,struct tripleList *list3,int rowPot1[],int rowPot2[])
{
int i,j,k,l,no,max,n,len1,len2,A[2000]={0};
list3->li=list1->li;//得到行列
list3->lj=list2->lj;
for (i=0,n=0;i<=list1->li-1;i++)//遍历第一个矩阵的行
{
len1=rowPot1[i+1]-1;/得到这一行的所有非0元在三元组表的位置区间的右端
for (j=rowPot1[i],max=0;j<=len1;j++)//在这一行所有非0元在三元组表中的位置区间中遍历
{
len2=rowPot2[list1->T[j].tj+1]-1;//得到第二个矩阵中列号与上一个for中的行号相等的所有非0元在三元组表的位置区间的最左端
for (k=rowPot2[list1->T[j].tj];k<=len2;k++)//在这一行所有非0元在三元组表中的位置区间遍历
{
no=list2->T[k].tj;
A[no]+=list1->T[j].value*list2->T[k].value;//在数组中添加相乘结果
max=no>max?no:max;
}
}
for (l=0;l<=max;l++)
{
if (A[l]!=0)//将非0的结果存入新的三元组表中
{
list3->T[n].ti=list1->T[j-1].ti;
list3->T[n].tj=l;
list3->T[n].value=A[l];
++n;
A[l]=0;
}
}
}
list3->ln=n;//得到新三元组表的元素个数
}
void printTripleList (struct tripleList *list)
{
int i;
for (i=0;i<=list->ln-1;i++)//输出三元组表的所有元素
{
printf ("%d %d %d\n",list->T[i].ti+1,list->T[i].tj+1,list->T[i].value);
}
}
void run ()
{
int rowPot1[2000]={0},rowPot2[2000]={0};
struct tripleList list1,list2,list3;
createNewTripleList (&list1);//输入两个三元组表
createNewTripleList (&list2);
getRowPot (&list1,rowPot1);//得到它们的位置数组
getRowPot (&list2,rowPot2);
mul (&list1,&list2,&list3,rowPot1,rowPot2);//相乘
printTripleList (&list3);//输出
}
以上就是我的实现,希望给大家带来帮助。