矩阵计算

【问题描述】
矩阵是线性代数中的重要概念,应用领域非常广泛,在C/C++中,通常将矩阵定义为一个二维数组。
本问题中,将输入两个矩阵 A 和 B,实现对矩阵的数乘、矩阵加法、矩阵乘法以及行列式的计算。
如果对矩阵的算法不了解,请查阅相关资料。

【输入形式】
输入的第一行为两个正整数 M 和 N,分别表示矩阵 A 的行数和列数;
接下来的 M 行,每行 N 个用空格分隔的整数,表示矩阵 A 的元素值;
接下来的一行,为一个整数 x, 用于对矩阵 A 进行数乘;
接下来的一行为两个正整数 K 和 L, 分别表示矩阵 B 的行数和列数;
接下来的 K 行,每行为 L 个用空格分隔的整数,表示矩阵 B 的元素值。

【输出形式】
输出的第一部分为 M 行,每行为 N 个用空格分隔的整数,表示 x 数乘 A 的结果;
接下来(如果有),如果 A 和 B 可以相加,则输出 M 行,每行为 N 个用空格分隔的整数,表示矩阵 A+B 的结果;
接下来(如果有),如果 A 和 B 可以相乘,则输出 M 行,每行为 L 个用空格分隔的整数,表示矩阵 A×B 的结果;
接下来一行(如果有),如果 A 的行列式存在,则输出一个整数,表示 A 的行列式的值;
接下来一行(如果有),如果 B 的行列式存在,则输出一个整数,表示 B 的行列式的值。

【样例输入1】
2 2
29 51
7 84
9
2 9
1 1 4 8 5 7 4 5 9
2 5 5 1 6 1 4 8 6

【样例输出1】
261 459
63 756
131 284 371 283 451 254 320 553 567
175 427 448 140 539 133 364 707 567
2079

【样例输入2】
5 3
71 15 54
24 56 8
61 34 50
82 94 88
48 7 43
3
5 3
2 1 5
1 7 1
0 1 6
4 1 9
2 8 7

【样例输出2】
213 45 162
72 168 24
183 102 150
246 282 264
144 21 129
73 16 59
25 63 9
61 35 56
86 95 97
50 15 50

【样例输入3】
4 4
55 73 66 16
57 65 43 25
61 3 15 4
16 94 82 48
7
4 4
6 3 6 7
7 9 5 4
8 3 1 5
5 9 1 3

【样例输出3】
385 511 462 112
399 455 301 175
427 21 105 28
112 658 574 336
61 76 72 23
64 74 48 29
69 6 16 9
21 103 83 51
1449 1164 777 1055
1266 1110 735 949
527 291 400 526
1650 1572 696 1042
-2657450
-783

【样例输入4】
5 5
0 51 71 79 28
3 10 66 36 57
23 21 6 27 85
1 21 49 62 31
54 31 47 64 21
11
4 3
3 4 5
2 6 0
7 3 9
5 6 9

【样例输出4】
0 561 781 869 308
33 110 726 396 627
253 231 66 297 935
11 231 539 682 341
594 341 517 704 231
-299004213

【有关矩阵计算的知识】

1.矩阵的数乘:把给定的数字与矩阵的每个元素分别相乘
2.行列式计算:
n阶行列式,设
在这里插入图片描述
是由排成n阶方阵形式的n^2个数a(ij)(i,j=1,2,…,n) 确定的一个数,其值为n!项之和
在这里插入图片描述式中k1,k2,…,kn是将序列1,2,…n的元素次序交换k次所得到的一个序列,求和符号表示对k1,k2,…,kn取遍1,2,…n的一切排列求和,那末数D称为n阶方阵相应的行列式。例如,四阶行列式是4!个形为在这里插入图片描述的项的和,而其中a13a21a34a42相应于k=3,即该项前端的符号应为(-1)^3。
以三阶行列式A为例:
在这里插入图片描述
*利用代数余子式求解行列式:(可结合相关代码理解)
代数余子式的作用是把n阶行列式化简为n-1阶行列式。
由三阶行列式的求解公式可以得到:
在这里插入图片描述
我们定义a(ij)的代数余子式:将原行列式的第i行与第j列抹去后得到的n-1阶行列式记为C(ij),i+j 为偶数时取+,i+j为奇数时取- 。符号规律如下图:
在这里插入图片描述
例如a11的代数余子式 C11:
在这里插入图片描述
将行列式A沿第一行展开:
在这里插入图片描述
(代数余子式介绍内容来自网址:MIT线性代数—行列式公式和代数余子式

3.矩阵相乘:
设A为mp的矩阵,B为pn的矩阵,那么称m*n的矩阵C为矩阵A与B的乘积,记作C=AB,其中矩阵C中的第i行第j列元素可以表示为:
在这里插入图片描述
如下所示:
在这里插入图片描述

4.矩阵相加:当矩阵A和矩阵B的行数、列数都相同时,对应位置上的元素相加。

【示例代码】

#include  <iostream>
#include  <cstdlib>
using  namespace  std;
class  matrix
{
private:
        int  rows,  cols;
        int  **p;
public:
        matrix();
        matrix(int  &M,  int  &N);
        matrix(matrix  &A,  int  &&m,  int  &n);
        ~matrix();
        
        matrix  multi(int  x);      //  数乘
        int  det();                      //  计算行列式
        void  out();        //输出矩阵
        void  input();

        matrix  operator+(matrix  &another);  //重载加法运算实现矩阵相加
        matrix  operator*(matrix  &another);  //重载乘法运算实现矩阵相乘
};
matrix::matrix(int  &M,  int  &N)
{
        rows=M,  cols=N;
        p=new  int*[rows];
        for(int  i=0;i<M;i++)
        {
                p[i]=new  int[cols];
        }
}

matrix::matrix(matrix  &A,  int  &&m,  int  &n)      //从矩阵A中删除第m行第n列后得到新的矩阵
{
        rows=A.rows-1,  cols=A.cols-1;
        p=new  int*[rows];
        for(int  i=0;i<rows;i++)
        {
                p[i]=new  int[cols];
        }
        for(int  i=0;  i<m;  i++)
                for(int  j=0;  j<n;  j++)
                      p[i][j]=A.p[i][j];

        for(int  i=0;  i<m;  i++)
                for(int  j=n+1;  j<A.cols;  j++)
                      p[i][j-1]=A.p[i][j];

        for(int  i=m+1;  i<A.rows;  i++)
                for(int  j=0;  j<n;  j++)
                      p[i-1][j]=A.p[i][j];

        for(int  i=m+1;  i<A.rows;  i++)
                for(int  j=n+1;  j<A.cols;  j++)
                      p[i-1][j-1]=A.p[i][j];
}

matrix::~matrix()
{
        for(int  i=0;  i<rows;  i++)
                delete[]  p[i];
        delete[]  p;
}

matrix  matrix::multi(int  x)      //  数乘
{
        matrix  tmp(rows,  cols);
        for (int i=0;i<rows;i++)
        {
            for(int j=0;j<cols;j++)
            {
                tmp.p[i][j]=this->p[i][j]*x;
            }
        }
        return  tmp;
}

void  matrix::out()        //输出矩阵
{
          /*  逐行输出,数据间用空格分隔  */
        for(int  i=0;  i<rows;  i++)
         {
              for(int  j=0;  j<cols;  j++)
                  {
                      cout<<p[i][j]<<' ';
                  }
                cout<<endl;
         }
}

void  matrix::input()
{
        for(int  i=0;  i<rows;  i++)
                for(int  j=0;  j<cols;  j++)
                        cin>>p[i][j];

}

matrix  matrix::operator+(matrix  &another)  //重载加法运算实现矩阵相加
{
        matrix  tmp(rows,  cols);
        /*  矩阵对应位置元素相加  */
        for(int i=0;i<rows;i++)
        {
            for(int j=0;j<cols;j++)
            {
                tmp.p[i][j]=this->p[i][j]+another.p[i][j];
            }
        }
        return  tmp;
}

matrix  matrix::operator*(matrix  &another)    //重载乘法运算实现矩阵相乘
{
        matrix  tmp(rows,  another.cols);
        for(int  i=0;  i<rows;  i++)
        {
                for(int  j=0;  j<another.cols;  j++)
                {
                      /*  计算A矩阵的第i行与B矩阵的第j列元素对应相乘后之和,作为新矩阵的第i行第j列元素的值  */
                      tmp.p[i][j]=0;
                      for(int k=0;k<cols;k++)
                      {
                          tmp.p[i][j]=tmp.p[i][j]+((this->p[i][k])*(another.p[k][j]));
                      }
                }
        }
        return  tmp;
}

int  matrix::det()
{
        if  (rows==1)
                return  p[0][0];
        else
        {
                int  result=0,  flag;
                for(int  i=0;  i<cols;  i++)
                {
                        flag=(i%2)?-1:1;
                        matrix  tmp(*this,  0,  i);
                        result=result+flag*p[0][i]*tmp.det();        //  使用代数余子式求行列式的值,  递归
                }
                return  result;
        }
}
int  main()
{
        int  M,N;
        //  A矩阵的行和列
        cin>>M>>N;
        matrix  mA(M,  N);        //生成A矩阵
        //  输入矩阵值
        mA.input();
        //  输入数乘值
        int  x;
        cin>>x;
        matrix  mm1=mA.multi(x);
        mm1.out();
        //B矩阵的行和列
        int  K,  L;
        cin>>K>>L;
        matrix  mB(K,  L);    //生成B矩阵
        mB.input();
        /*  求矩阵A和矩阵B的和  */
        if  (M==K  &&  N==L)
        {
                matrix  mm2=mA+mB;
                mm2.out();
        }
      /*  求矩阵A和矩阵B的乘积矩阵  */
        if  (N==K)
        {
                matrix  mm3=mA*mB;
                mm3.out();
        }
        /*  矩阵A的行列式的值  */
        if  (M==N)
                cout<<mA.det()<<endl;
        if  (K==L)
                cout<<mB.det()<<endl;
        return  0;
}
  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LG.田猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值