鱼C论坛

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

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

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

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

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

x
本帖最后由 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[101][101], arr2[101][101], arr3[202][202];

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[i][j]);
        fscanf(fin,"\n");
    }
    for(i = 1;i<=a;i++)
    {
        for(j = 1;j<=b;j++)
            fscanf(fin,"%d",&arr2[i][j]);
        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[j][x1]*arr2[x1][k];
            arr3[cx][cy] = 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[i][j]);
        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 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就得交换,就像这样
for(int i = 0; i < y ; i++)
{
    for(int j = 0; j < x; j++);
}
这样就可以避免不必要的越界
程序模拟一下
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, 2025-1-15 13:39

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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