题解 | #矩阵乘法#

矩阵乘法

http://www.nowcoder.com/practice/ebe941260f8c4210aa8c17e99cbc663b

矩阵乘法

描述

如果A是个x行y列的矩阵,B是个y行z列的矩阵,把A和B相乘,其结果将是另一个x行z列的矩阵C。这个矩阵的每个元素是由下面的公式决定的
\begin{equation*}<br /><br />C_{ij} = \sum_{k=0}^{y-1}A_{ik}*B_{kj}<br /><br />\end{equation*} (其中0 \leq i < x, 0 \leq j < y)
矩阵的大小不超过100*100
输入描述:
输入包含多组数据,每组数据包含:
第一行包含一个正整数x,代表第一个矩阵的行数
第二行包含一个正整数y,代表第一个矩阵的列数和第二个矩阵的行数
第三行包含一个正整数z,代表第二个矩阵的列数
之后x行,每行y个整数,代表第一个矩阵的值
之后y行,每行z个整数,代表第二个矩阵的值
输出描述:
对于每组输入数据,输出x行,每行z个整数,代表两个矩阵相乘的结果

示例1

输入:
2
3
2
1 2 3
3 2 1
1 2
2 1
3 3
输出:
14 13
10 11
说明:
1 2 3
3 2 1 
乘以
1 2
2 1
3 3
等于
14 13
10 11  

示例2

输入:
2
2
2
1 1
1 1
1 1
1 1
16
8
7
17 19 16 19 14 1 14 9 
7 2 7 9 16 14 16 12 
13 3 3 17 5 9 8 16 
1 14 16 10 13 13 14 1 
13 13 15 4 7 2 6 16 
16 15 5 5 15 13 1 11 
11 5 0 16 14 7 7 15 
0 16 4 7 16 6 0 15 
2 14 11 2 17 17 5 12 
8 13 11 10 1 17 10 8 
15 16 17 15 7 8 13 14 
5 19 11 3 11 14 5 4 
9 16 13 11 15 18 0 3 
15 3 19 9 5 14 12 3 
9 8 7 11 18 19 14 18 
12 19 9 1 0 18 17 10 
5 18 16 19 6 12 5 
1 17 1 5 9 16 3 
14 16 4 0 19 3 6 
11 9 15 18 11 17 13 
5 5 19 3 16 1 12 
12 13 19 1 10 5 18 
19 18 6 18 19 12 3 
15 11 6 5 10 17 19 
输出:
2 2
2 2
1020 1490 1063 1100 1376 1219 884
966 1035 1015 715 1112 772 920
822 948 888 816 831 920 863
855 1099 828 578 1160 717 724
745 1076 644 595 930 838 688
635 1051 970 600 880 811 846
748 879 952 772 864 872 878
526 722 645 335 763 688 748
764 996 868 362 1026 681 897
836 1125 785 637 940 849 775
1082 1476 996 968 1301 1183 953
609 987 717 401 894 657 662
700 1083 1022 527 1016 746 875
909 1162 905 722 1055 708 720
1126 1296 1240 824 1304 1031 1196
905 1342 766 715 1028 956 749

方法一

思路分析

本题方法一直接根据矩阵乘法的方法进行计算。设A为m行p列的矩阵,B为p行n列的矩阵,那么称矩阵C为矩阵A与B的乘积,其中矩阵C中的第i行第j列元素可以表示为:
\begin{equation*}<br /><br />C_{ij} = \sum_{k=0}^{p}A_{ik}*B_{kj}=\sum_{k=0}^{p}a_{ik}*b_{kj}=a_{i1}*b_{1j}+a_{i2}*b_{2j}+...+a_{ip}*b_{pj}<br /><br />\end{equation*}

核心代码

#include<bits/stdc++.h>
using namespace std;
int main()
{
    
    int n=0,m=0,p=0;
    while(cin>>n>>m>>p)
    {
        vector<vector<int>>arr1(n+1,vector<int>(m+1,0));//存储矩阵数组
        vector<vector<int>>arr2(m+1,vector<int>(p+1,0));
        vector<vector<int>>arr3(n+1,vector<int>(p+1,0));//存储结果数组
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                cin>>arr1[i][j];
            }
        }
        for(int j=1;j<=m;j++)
        {
            for(int k=1;k<=p;k++)
            {
                cin>>arr2[j][k];
            }
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=p;j++)
            {
                for(int k=1;k<=m;k++)
                {
                    arr3[i][j]+=arr1[i][k]*arr2[k][j];//矩阵每一个位置的元素计算
                }
            }
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=p;j++)
                cout<<arr3[i][j]<<" ";
            cout<<endl;
        }
    }
}

复杂度分析
  • 时间复杂度:时间主要消耗在计算矩阵的每一个位置元素,三层循环嵌套,因此时间复杂度$O(m*n*k)$,其中m,n表示第一个矩阵的行数与列数,k表示第二个矩阵的列数
  • 空间复杂度:本方法并没有直接的额外空间的使用,因此空间复杂度为$O(1)$

方法二

思路分析

对于方法一中的三层嵌套循环求解结果矩阵的每一个元素,可以通过分析调整嵌套的次序,从而节省时间开销。进行如下调整,根据计算机内部的存取方式在访问arr3[i][j]和arr2[k][j]时不会跳跃,从而减少开销。
for(int k=1;k<=m;k++)
{
    for(int i=1;i<=n;i++)
    {
        int r=arr1[i][k];
        for(int j=1;j<=p;j++)
        {
            arr3[i][j]+=r*arr2[k][j];//矩阵计算方式
        }
    }
}

核心代码

#include<bits/stdc++.h>
using namespace std;
int main()
{
    
    int n=0,m=0,p=0;
    while(cin>>n>>m>>p)
    {
        vector<vector<int>>arr1(n+1,vector<int>(m+1,0));//存储矩阵数组
        vector<vector<int>>arr2(m+1,vector<int>(p+1,0));
        vector<vector<int>>arr3(n+1,vector<int>(p+1,0));//存储结果数组
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                cin>>arr1[i][j];
            }
        }
        for(int j=1;j<=m;j++)
        {
            for(int k=1;k<=p;k++)
            {
                cin>>arr2[j][k];
            }
        }
        for(int k=1;k<=m;k++)
        {
            for(int i=1;i<=n;i++)
            {
                int r=arr1[i][k];
                for(int j=1;j<=p;j++)
                {
                    arr3[i][j]+=r*arr2[k][j];//矩阵计算方式
                }
            }
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=p;j++)
                cout<<arr3[i][j]<<" ";
            cout<<endl;
        }
    }
}
复杂度分析
  • 时间复杂度:时间主要消耗在计算矩阵的每一个位置元素,三层循环嵌套,较方法一时间会减小,不过时间复杂度仍为$O(m*n*k)$,其中m,n表示第一个矩阵的行数与列数,k表示第二个矩阵的列数
  • 空间复杂度:本方法并没有直接的额外空间的使用,因此空间复杂度为$O(1)$




全部评论

相关推荐

评论
点赞
1
分享

创作者周榜

更多
正在热议
更多
# 春招至今,你的战绩如何? #
13730次浏览 132人参与
# AI面会问哪些问题? #
813次浏览 19人参与
# 巨人网络春招 #
11461次浏览 224人参与
# 你的实习产出是真实的还是包装的? #
2431次浏览 47人参与
# AI时代,哪个岗位还有“活路” #
2495次浏览 49人参与
# 长得好看会提高面试通过率吗? #
2446次浏览 39人参与
# MiniMax求职进展汇总 #
24614次浏览 313人参与
# 你做过最难的笔试是哪家公司 #
1020次浏览 18人参与
# HR最不可信的一句话是__ #
914次浏览 31人参与
# 沪漂/北漂你觉得哪个更苦? #
908次浏览 29人参与
# 军工所铁饭碗 vs 互联网高薪资,你会选谁 #
7898次浏览 43人参与
# XX请雇我工作 #
51120次浏览 171人参与
# 简历中的项目经历要怎么写? #
310766次浏览 4252人参与
# 简历第一个项目做什么 #
31981次浏览 354人参与
# 不考虑薪资和职业,你最想做什么工作呢? #
152726次浏览 888人参与
# 当下环境,你会继续卷互联网,还是看其他行业机会 #
187495次浏览 1123人参与
# AI时代,哪些岗位最容易被淘汰 #
64398次浏览 857人参与
# 如果重来一次你还会读研吗 #
229937次浏览 2011人参与
# 正在春招的你,也参与了去年秋招吗? #
364032次浏览 2640人参与
# 腾讯音乐求职进展汇总 #
160794次浏览 1114人参与
# 你怎么看待AI面试 #
180527次浏览 1287人参与
# 投格力的你,拿到offer了吗? #
178044次浏览 889人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务