juhugufudu 发表于 2020-4-2 16:01:51

两个矩阵的相乘

本帖最后由 juhugufudu 于 2020-4-2 16:04 编辑

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

void how_to_x_y()
{
    if(n > b) {y = n; }
    else {y = b; }
    if(m < a) {x = m;}
    else {x = a; }
}
void init()
{
    fscanf(fin,"%d %d\n",&m,&n);
    fscanf(fin,"%d %d\n",&a,&b);
    int i, j;
    for(i = 1;i<=m;i++)
    {
      for(j = 1;j<=n;j++)
            fscanf(fin,"%d",&arr);
      fscanf(fin,"\n");
    }
    for(i = 1;i<=a;i++)
    {
      for(j = 1;j<=b;j++)
            fscanf(fin,"%d",&arr2);
      fscanf(fin,"\n");
    }
}
int main()
{
    int cx = 1, cy = 1; //C 矩阵的赋值x, y
    int i , j, k, x1; //循环变量

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

    init(); //输入
    how_to_x_y();//判断 C 矩阵到底要几行几列
    long sum = 0;
    for(j = 1;j<=n;j++)
    {
      for(k = 1;k<=b;k++)
      {
            for(x1 = 1;x1<=a;x1++)
                sum += arr*arr2;
            arr3 = sum;
            if(cy == y)
            {
                if(cx == x)
                  goto A;
                cy = 1;
                cx += 1;
            }
            else {cy += 1;}
            sum = 0;
      }
    }
A:
    for(i = 1;i<=x;i++)
    {
      for(j = 1;j<=y;j++)
            printf("%d ",arr3);
      printf("\n");
    }

    fclose(fin);
    return 0;
}
这个,需要一个文件fin(文件名是home.in)
在里面写如下几行字
4 5
5 8
1 2 3 4 5
2 2 2 2 2
3 3 3 3 3
5 4 3 2 1
8 7 6 5 4 3 2 1
1 1 1 1 1 1 1 1
2 2 2 2 2 2 2 2
3 3 3 3 3 3 3 3
1 2 3 4 5 6 7 8对的,然后运行代码就可以啦~~~
我的思路就是这样的
首先,输入。
然后,对比 两个矩阵的值来确定第三个矩阵的值(长和宽)
通过我的观察,C矩阵的长是两个(A,B)两个矩阵的长中的最大值
然后,宽是最小值。
C矩阵的每一个元素都是A矩阵的每一元素与B矩阵的元素的乘积然后相加得到的
就是这样
1 2 3 4 5
2 2 2 2 2
3 3 3 3 3
5 4 3 2 1
8 7 6 5 4 3 2 1
1 1 1 1 1 1 1 1
2 2 2 2 2 2 2 2
3 3 3 3 3 3 3 3
1 2 3 4 5 6 7 812345 -- 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 就是指第一行第二列的值。
那么,我们要竖着取,就可以把x, y倒过来一下
如 : B -- > B
那么,这个的x, y就得交换,就像这样
for(int i = 0; i < y ; i++)
{
    for(int j = 0; j < x; j++);
}
这样就可以避免不必要的越界
程序模拟一下
B 模拟
B
B
B
B
B
B
B
B
B
B
========
=====取值范围=======
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*\
B;

    }

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

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



juhugufudu 发表于 2020-4-2 16:03:10

重要的东西,我放在main函数里了~~~~
页: [1]
查看完整版本: 两个矩阵的相乘