【问题描述】
稀疏矩阵可以以压缩方式进行存储,即:用一个n行3列矩阵只存储非零元素。每行存储一个非零元素,每行第一个为非零元素行标;第二个为非零元素列标;第三个为非零元素本身。如下左边为一个稀疏矩阵,右边是其存储形式。编写程序实现用上述压缩存储方式输入的稀疏矩阵的乘法,稀疏矩阵最大为9*9。以压缩方式输出结果矩阵。行标和列标都从0开始计数。
0 0 0 10 0 3 10
2 0 0 0 1 0 2
0 0 3 1 2 2 3
1 0 0 0 2 3 1
3 0 1
【输入形式】
先从控制台输入第一个矩阵的非零元素个数,再以压缩方式输入第一个矩阵的元素,即:分行输入非零元素的行标、列标和非零元素数据本身,以一个空格分隔行标、列标和非零元素。然后以同样方式输入第二个矩阵。
【输出形式】
在标准输出上以压缩方式分行输出结果矩阵,即:每行分别输出结果矩阵中非零元素的行标、列标和非零元素数据本身,行标、列标和非零数据之间以一个空格分隔,但每行最后一个数据后没有空格。先输出行标小的元素,若行标相同,则先输出列标小的元素。若没有非零元素,则不输出任何信息。
【输入样例】
5
0 3 10
1 0 2
2 2 3
2 3 1
3 0 1
2
0 1 200
2 2 -5
【输出样例】
1 1 400
2 2 -15
3 1 200
【样例说明】
输入的两个矩阵中的行、列最大下标均为3,所以可以看成是4*4的矩阵,即输入的两个矩阵分别为:
0 0 0 10
2 0 0 0
0 0 3 1
1 0 0 0
0 200 0 0
0 0 0 0
0 0 -5 0
0 0 0 0
两矩阵相乘的结果为:
0 0 0 0
0 400 0 0
0 0 -15 0
0 200 0 0
算法说明
在解决此题时采取了比较直观的解决方法。
- 读取输入到数组中
- 将输入形成的数组还原为正常的矩阵形式(取两矩阵行列数最大值作为矩阵行列数)
- 将第一个矩阵的每一行与第二个矩阵的每一列相乘并输出运算结果
代码如下:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n1,n2,i,j,m,n,k;
scanf("%d",&n1); //读取第一个稀疏矩阵
int a1[n1][3];
int y1_max=0;
for(i=0;i<n1;i++){
scanf("%d",&a1[i][0]);
scanf("%d",&a1[i][1]);
scanf("%d",&a1[i][2]);
if(a1[i][1] > y1_max)
y1_max = a1[i][1]; //矩阵一最大列数
}
int x1_max = a1[n1-1][0]; //矩阵一最大行数
scanf("%d",&n2);//读取第二个稀疏矩阵
int a2[n2][3];
int y2_max=0;
for(j=0;j<n2;j++){
scanf("%d",&a2[j][0]);
scanf("%d",&a2[j][1]);
scanf("%d",&a2[j][2]);
if(a2[j][1]>y2_max)
y2_max = a2[j][1]; //矩阵二最大列数
}
int x2_max = a2[n2-1][0]; //矩阵二最大行数
//取两矩阵行数列数最大值,作为生成矩阵的行列数
int max = x1_max;
if(y1_max>max)
max = y1_max;
if(x2_max>max)
max = x2_max;
if(y2_max>max)
max = y2_max;
max+=1;
int x1,y1,t1,x2,y2,t2;
int x[max][max]; //按行数还原为矩阵
int y[max][max]; //按列数还原为矩阵
for(m=0;m<max;m++) //矩阵初始化
for(n =0;n<max;n++){
x[m][n]=0;
y[m][n]=0;
}
for(i=0;i<n1;i++){ //计算两矩阵相乘结果
x1 = a1[i][0];
y1 = a1[i][1];
t1 = a1[i][2];
x[x1][y1]=t1;
}
for(j=0;j<n2;j++){
x2 = a2[j][0];
y2 = a2[j][1];
t2 = a2[j][2];
y[y2][x2] = t2;
}
//计算矩阵乘积
int total;
for(m=0;m<max;m++)
for(n=0;n<max;n++){
total = 0;
for(k=0;k<max;k++){
total+=x[m][k]*y[n][k];
}
if(total != 0)
printf("%d %d %d\n",m,n,total);
}
return 0;
}
明天学习一下效率更高的算法再贴上来。