目录
对于矩阵而言,我们首先要学习他的基本概念,其次就如同学习常规数字一样需要掌握基本的加减乘,再者,更具相关的概念学会求诸如秩,点阵,矩阵运算值等,接着学习一些特殊的矩阵操作,如矩阵的翻转,最后这些概念完善之后,请开始学习诸如矩阵的卷积核运算,稀疏矩阵,增广矩阵等这些特殊的矩阵。
矩阵加法
运算规则,将两个矩阵的每一行每一列进行对齐,再直接进行元素间的相加,如a11和b11相加,详情参考图,如:
简言之,两个矩阵相加,即它们相同位置的元素相加!
注意:只有对于两个行数、列数分别相等的矩阵(即同型矩阵),加减法运算才有意义,即加减运算是可行的.同时,对于加法而言,A+B与B+A是没有什么不同的,他们的结果运算是一样的,详情可以参考代码:
#include <stdio.h>
#define MAXN 505
int a[MAXN][MAXN];
int b[MAXN][MAXN];
int ans[MAXN][MAXN];
int main() {
// 矩阵加法
int n, m;
scanf("%d %d", &n, &m);
// 输入矩阵 a
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
scanf("%d", &a[i][j]);
}
}
// 输入矩阵 b
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
scanf("%d", &b[i][j]);
}
}
// 矩阵相加
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
ans[i][j] = a[i][j] + b[i][j];
}
}
// 输出结果
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
printf("%d ", ans[i][j]);
}
printf("\n");
}
return 0;
}
矩阵减法
通上文,简言之,两个矩阵相减,即它们相同位置的元素相减!
对于上文而言,我们只需要在算法中将符号+替换成符号-进行减法运算即可。
简言之,两个矩阵相加减,即它们相同位置的元素相加减!
#include <stdio.h>
#define MAXN 505
int a[MAXN][MAXN];
int b[MAXN][MAXN];
int ans[MAXN][MAXN];
int main() {
// 矩阵相减
int n, m;
scanf("%d %d", &n, &m);
// 输入矩阵 a
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
scanf("%d", &a[i][j]);
}
}
// 输入矩阵 b
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
scanf("%d", &b[i][j]);
}
}
// 矩阵相减
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
ans[i][j] = a[i][j] - b[i][j];
}
}
// 输出结果
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
printf("%d ", ans[i][j]);
}
printf("\n");
}
return 0;
}
练习:将加减乘除写一个简单的类
从C一路学习到C++,我们了解了面向对象的设计思路,那么,就让我们结合上一节学习的乘除法,设计一个简单的矩阵运算类,这样的设计,有助于以后的多次使用。
要求,(一阶段)在自己的电脑上使用C++编程软件,设计一个类,其中要保证可以输入两个矩阵,然后设计类的方法,方法包括实现加减乘等基本运算,可以使用符号重载的方式进行优化实现。
(二阶段)可以扩展一些其余的快速算法,如矩阵的幂运算(多个矩阵相乘)乃至快速幂运算(利用特殊的计算机技巧进行快速多矩阵相乘)。
#include <iostream>
#include <vector>
using namespace std;
class Matrix {
private:
vector<vector<int>> data;
int rows, cols;
public:
// 构造函数
Matrix(int r, int c) : rows(r), cols(c) {
data.resize(r, vector<int>(c, 0));
}
// 输入矩阵
void input() {
cout << "Enter matrix elements (" << rows << "x" << cols << "):" << endl;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
cin >> data[i][j];
}
}
}
// 输出矩阵
void display() const {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
cout << data[i][j] << ' ';
}
cout << endl;
}
}
// 矩阵加法
Matrix operator+(const Matrix& other) {
if (rows != other.rows || cols != other.cols) {
throw invalid_argument("Matrix dimensions must agree for addition.");
}
Matrix result(rows, cols);
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
result.data[i][j] = data[i][j] + other.data[i][j];
}
}
return result;
}
// 矩阵减法
Matrix operator-(const Matrix& other) {
if (rows != other.rows || cols != other.cols) {
throw invalid_argument("Matrix dimensions must agree for subtraction.");
}
Matrix result(rows, cols);
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
result.data[i][j] = data[i][j] - other.data[i][j];
}
}
return result;
}
// 矩阵乘法
Matrix operator*(const Matrix& other) {
if (cols != other.rows) {
throw invalid_argument("Matrix dimensions must agree for multiplication.");
}
Matrix result(rows, other.cols);
for (int i = 0; i < rows; i++) {
for (int j = 0; j < other.cols; j++) {
for (int k = 0; k < cols; k++) {
result.data[i][j] += data[i][k] * other.data[k][j];
}
}
}
return result;
}
};
int main() {
int n1, m1, n2, m2;
// 输入第一个矩阵的维度
cout << "Enter dimensions of first matrix (rows columns): ";
cin >> n1 >> m1;
Matrix A(n1, m1);
A.input();
// 输入第二个矩阵的维度
cout << "Enter dimensions of second matrix (rows columns): ";
cin >> n2 >> m2;
Matrix B(n2, m2);
B.input();
// 矩阵加法
try {
Matrix C = A + B;
cout << "Matrix A + B:" << endl;
C.display();
} catch (const invalid_argument& e) {
cout << e.what() << endl;
}
// 矩阵减法
try {
Matrix D = A - B;
cout << "Matrix A - B:" << endl;
D.display();
} catch (const invalid_argument& e) {
cout << e.what() << endl;
}
// 矩阵乘法
try {
Matrix E = A * B;
cout << "Matrix A * B:" << endl;
E.display();
} catch (const invalid_argument& e) {
cout << e.what() << endl;
}
return 0;
}