鱼C论坛

 找回密码
 立即注册
查看: 748|回复: 1

[技术交流] 两个矩阵的相乘

[复制链接]
发表于 2020-4-2 16:01:51 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 juhugufudu 于 2020-4-2 16:04 编辑
相信大家都学过矩阵的加法把,我想了很久,才想出这个不怎么好的方案。
注:因为我的编译器太老了,不支持数组的[]里写变量,所以,我的代码不太好……
  1. #include<stdio.h>
  2. FILE *fin, *fout;
  3. int m, n; //A 矩阵的长和宽
  4. int a, b; //B 矩阵的长和宽
  5. int x, y; //C 矩阵的长和宽
  6. int arr[101][101], arr2[101][101], arr3[202][202];

  7. void how_to_x_y()
  8. {
  9.     if(n > b) {y = n; }
  10.     else {y = b; }
  11.     if(m < a) {x = m;}
  12.     else {x = a; }
  13. }
  14. void init()
  15. {
  16.     fscanf(fin,"%d %d\n",&m,&n);
  17.     fscanf(fin,"%d %d\n",&a,&b);
  18.     int i, j;
  19.     for(i = 1;i<=m;i++)
  20.     {
  21.         for(j = 1;j<=n;j++)
  22.             fscanf(fin,"%d",&arr[i][j]);
  23.         fscanf(fin,"\n");
  24.     }
  25.     for(i = 1;i<=a;i++)
  26.     {
  27.         for(j = 1;j<=b;j++)
  28.             fscanf(fin,"%d",&arr2[i][j]);
  29.         fscanf(fin,"\n");
  30.     }
  31. }
  32. int main()
  33. {
  34.     int cx = 1, cy = 1; //C 矩阵的赋值x, y
  35.     int i , j, k, x1; //循环变量

  36.     fin = fopen("home.in","r");

  37.     init(); //输入
  38.     how_to_x_y();//判断 C 矩阵到底要几行几列
  39.     long sum = 0;
  40.     for(j = 1;j<=n;j++)
  41.     {
  42.         for(k = 1;k<=b;k++)
  43.         {
  44.             for(x1 = 1;x1<=a;x1++)
  45.                 sum += arr[j][x1]*arr2[x1][k];
  46.             arr3[cx][cy] = sum;
  47.             if(cy == y)
  48.             {
  49.                 if(cx == x)
  50.                     goto A;
  51.                 cy = 1;
  52.                 cx += 1;
  53.             }
  54.             else {cy += 1;}
  55.             sum = 0;
  56.         }
  57.     }
  58. A:
  59.     for(i = 1;i<=x;i++)
  60.     {
  61.         for(j = 1;j<=y;j++)
  62.             printf("%d ",arr3[i][j]);
  63.         printf("\n");
  64.     }

  65.     fclose(fin);
  66.     return 0;
  67. }
复制代码
这个,需要一个文件fin(文件名是home.in)
在里面写如下几行字
  1. 4 5
  2. 5 8
  3. 1 2 3 4 5
  4. 2 2 2 2 2
  5. 3 3 3 3 3
  6. 5 4 3 2 1
  7. 8 7 6 5 4 3 2 1
  8. 1 1 1 1 1 1 1 1
  9. 2 2 2 2 2 2 2 2
  10. 3 3 3 3 3 3 3 3
  11. 1 2 3 4 5 6 7 8
复制代码
对的,然后运行代码就可以啦~~~
我的思路就是这样的
首先,输入。
然后,对比 两个矩阵的值来确定第三个矩阵的值(长和宽)
通过我的观察,C矩阵的长是两个(A,B)两个矩阵的长中的最大值
然后,宽是最小值。
C矩阵的每一个元素都是A矩阵的每一元素与B矩阵的元素的乘积然后相加得到的
就是这样
  1. 1 2 3 4 5
  2. 2 2 2 2 2
  3. 3 3 3 3 3
  4. 5 4 3 2 1
  5. 8 7 6 5 4 3 2 1
  6. 1 1 1 1 1 1 1 1
  7. 2 2 2 2 2 2 2 2
  8. 3 3 3 3 3 3 3 3
  9. 1 2 3 4 5 6 7 8
复制代码
12345 -- 81231
所以C矩阵的第一个元素就可得出:
1 * 8 + 2 * 1 + 3 * 3 + 5 * 1
得出后,A矩阵不变,B矩阵就是继续下列,结果作为C矩阵的下一个元素的值

2 2 2 2 2 -- 7 1 2 3 2
2 * 7 + 2 * 1 + 2* 2 + 2 * 3 + 2 * 2
当B矩阵遍历完后,就让A矩阵遍历下一行
2 2 2 2 2 --- 8 1 2 3 1
那,这应该如何转换为代码呢?
我们可以这样想,两重循环就可以遍历出 B 矩阵的每一个值,如B[1,2] 就是指第一行第二列的值。
那么,我们要竖着取,就可以把x, y倒过来一下
如 : B[1,2] -- > B[2,1]
那么,这个的x, y就得交换,就像这样
  1. for(int i = 0; i < y ; i++)
  2. {
  3.     for(int j = 0; j < x; j++);
  4. }
复制代码

这样就可以避免不必要的越界
程序模拟一下
B[j , i] 模拟
B[1,1]
B[2,1]
B[3,1]
B[4,1]
B[5,1]
B[1,2]
B[2,2]
B[3,2]
B[4,2]
B[5,2]
========
=====取值范围=======
B[(1~5),(1~8)]

如果这还没懂,很正常,我也是写着写着就懂了
还没结束!!!!!!!!!!!!!!!!
我们虽然已经完成了一个,但还有一个循环,那就是……
一:A矩阵的下一行可以用一个循环表示
二:关系:
for(int i = 1;i<=A矩阵的长;i++)
{
    for(int j = 1;j<=B矩阵的长;j++)
    {
     for(int x = 1;x<=B矩阵的宽;j++) sum = sum+A[x]*\
B[x][j];

    }

}
这个原因,大家应该清楚了,那就是我们的Code:

A的一行对应这B的所有列




想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-4-2 16:03:10 | 显示全部楼层
重要的东西,我放在main函数里了~~~~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-18 17:38

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表