【暑假例题】20230727 矩阵基本运算(C++)

发布时间 2023-07-31 22:51:06作者: 山远尽成云

题目

请使用C++实现矩阵的各种运算

  1. 矩阵创建
  2. 矩阵相加
  3. 矩阵相减
  4. 矩阵相乘
  5. 数字乘矩阵
  6. 矩阵上叠加
  7. 矩阵左右叠加
  8. 矩阵转置
  9. 矩阵旋转
  10. 矩阵求逆
  11. 矩阵输出

题目分析

矩阵创建

这里只需注意由于我们需要通过不同的函数对数组进行操作,所以我们需要将数组存储在容器或者使用指针防止数据丢失

const double epsilon = 1e-12;//小于该数判断为0

vector<vector<double>> v;//矩阵

vector<vector<double>> Create_Matrix(int h, int l)//创建 h行l列的矩阵,并将初始各值设定为0
{
	for (int i = 0; i < h; i++)
	{
		vector<double>v1(l, 0);
		v.push_back(v1);
	}
	return v;
}

矩阵相加、减、乘

需创建一个新的得数矩阵,并且注意两个矩阵对应位置相加减、乘即可

矩阵相加

vector<vector<double>> Matrix_add(const vector<vector<double>>& A, const vector<vector<double>>& B)//矩阵相加
{
	int h = A.size();
	int l = A[0].size();

	vector<vector<double>> C;
	C = Create_Matrix(h, l);//创建矩阵C

	for (int i = 0; i < h; i++)
	{
		for (int j = 0; j < l; j++)
		{
			C[i][j] = A[i][j] + B[i][j];
			if (abs(C[i][j]) < epsilon)
			{
				C[i][j] = 0;
			}
		}
	}
	return C;
}

矩阵相减

vector<vector<double>> Matrix_sub(const vector<vector<double>>& A, const vector<vector<double>>& B)//矩阵相减
{
	int h = A.size();
	int l = A[0].size();

	vector<vector<double>> C;
	C = Create_Matrix(h, l);//创建矩阵C

	for (int i = 0; i < h; i++)
	{
		for (int j = 0; j < l; j++)
		{
			C[i][j] = A[i][j] - B[i][j];
			if (abs(C[i][j]) < epsilon)
			{
				C[i][j] = 0;
			}
		}
	}
	return C;
}

矩阵相乘

vector<vector<double>> Matrix_mul(const vector<vector<double>>& A, const vector<vector<double>>& B)//矩阵相乘
{
	int A_h = A.size();
	int A_l = A[0].size();
	int B_h = B.size();
	int B_l = B[0].size();

	if (A_l != B_h)
	{
		cout << "两矩阵维数无法相乘" << endl;
		exit(0);
	}

	vector<vector<double>> C= Create_Matrix(A_h, B_l);//创建矩阵C
	for (int i = 0; i < A_h; i++)
	{
		for (int j = 0; j < B_l; j++)
		{
			C[i][j] = 0;
			for (int k = 0; k < A_l; k++)
			{
				C[i][j] += A[i][k] * B[k][j];
			}
			if (abs(C[i][j]) < epsilon)
			{
				C[i][j] = 0;
			}
		}
	}
	return C;
}

数字乘矩阵

矩阵里的每一个数乘数字就好了

vector<vector<double>> Matrix_x_num(const vector<vector<double>>& A, double num)//数字乘矩阵
{
	int A_h = A.size();
	int A_l = A[0].size();

	vector<vector<double>> B = Create_Matrix(A_h, A_l);//创建矩阵B

	for (int i = 0; i < A_h; i++)
	{
		for (int j = 0; j < A_l; j++)
		{
			B[i][j] = num * A[i][j];
		}
	}
	return B;
}

矩阵上叠加、矩阵左右叠加

先判断两个矩阵的列相等,然后分别导入两个矩阵进行叠加

矩阵上叠加

vector<vector<double>> Superposition_on_matrix(const vector<vector<double>>& A, const vector<vector<double>>& B)//矩阵A与矩阵B上下叠加获得新的矩阵C,并返回
{
	//判断矩阵的列是否相等
	int A_h = A.size();
	int A_l = A[0].size();
	int B_h = B.size();
	int B_l = B[0].size();

	if (A_l != B_l)
	{
		cout << "叠加的矩阵列数不相等" << endl;
		exit(0);
	}

	//创建
	vector<vector<double>> C = Create_Matrix(A_h + B_h, A_l);

	//将A传入
	for (int i = 0; i < A_h; i++)
	{
		for (int j = 0; j < A_l; j++)
		{
			C[i][j] = A[i][j];
		}
	}

	//将B传入
	for (int i = 0; i < B_h; i++)
	{
		for (int j = 0; j < B_l; j++)
		{
			C[i + A_h][j] = B[i][j];
		}
	}
	return C;
}

矩阵左右叠加

vector<vector<double>> L_R_Superposition_matrix(const vector<vector<double>>& A, const vector<vector<double>>& B)//矩阵A与矩阵B左右叠加,获得新的矩阵C
{
	//判断矩阵的列是否相等
	int A_h = A.size();
	int A_l = A[0].size();
	int B_h = B.size();
	int B_l = B[0].size();

	if (A_h != B_h)
	{
		cout << "叠加的矩阵行数不相等" << endl;
		exit(0);
	}

	//创建叠加后的矩阵C
	vector<vector<double>> C = Create_Matrix(A_h, A_l + B_l);

	//将A传入
	for (int i = 0; i < A_h; i++)
	{
		for (int j = 0; j < A_l; j++)
		{
			C[i][j] = A[i][j];
		}
	}

	//将B传入
	for (int i = 0; i < B_h; i++)
	{
		for (int j = 0; j < B_l; j++)
		{
			C[i][j + A_l] = B[i][j];
		}
	}
	return C;
}

矩阵转置、矩阵旋转

这部分可以看我做过的题目

https://www.cnblogs.com/hcrzhi/p/17538056.html

矩阵转置

vector<vector<double>> Matrix_device(const vector<vector<double>>& A)//矩阵转置
{
	vector<vector<double>> AT = Create_Matrix(A[0].size(), A.size());//AT为转置矩阵
	int l = AT.size();
	int c = AT[0].size();
	for (int i = 0; i < l; i++)
	{
		for (int j = 0; j < c; j++)
		{
			AT[i][j] = A[j][i];
		}
	}
	return AT;
}

矩阵旋转

vector<vector<double>> Matrix_rotation(const vector<vector<double>>& A)//矩阵旋转
{
	int l = A.size();
	int c = A[0].size();
	//水平翻转
	for (int i = 0; i < l / 2; i++)
	{
		for (int j = 0; j < l; j++)
		{
			swap(A[i][j], A[l - i - 1][j]);//交换函数
		}
	}

	//对角线翻转
	for (int i = 0; i < l; i++)
	{
		for (int j = 0; j < i; j++)
		{
			swap(A[i][j], A[j][i]);
		}
	}
	return A;
}

矩阵求逆

这里用到了一个LU分解,大家可以去看一下:https://blog.csdn.net/qq_28972011/article/details/123935820

vector<vector<double>> Matrix_inversion(const vector<vector<double>>& A)//矩阵求逆
{
	if (A.size() != A[0].size())
	{
		cout << "该矩阵无法求逆矩阵" << endl;
		exit(0);
	}
	int n = A.size();
	vector<vector<double>> inv_A = Create_Matrix(n, n);//逆矩阵
	vector<vector<double>> L = Create_Matrix(n, n);
	vector<vector<double>> U = Create_Matrix(n, n);
	vector<vector<double>> inv_L = Create_Matrix(n, n);
	vector<vector<double>> inv_U = Create_Matrix(n, n);//LU分解

	//L矩阵对角元素为1
	for (int i = 0; i < n; i++)
	{
		L[i][i] = 1;
	}

	//U矩阵第一行
	for (int i = 0; i < n; i++)
	{
		U[0][i] = A[0][i];
	}

	//L矩阵第一列
	for (int i = 0; i < n; i++)
	{
		U[0][i] = A[0][i];
	}

	//计算LU上下三角
	for (int i = 1; i < n; i++)
	{
		//计算U(i行j列)
		for (int j = i; j < n; j++)
		{
			double temp = 0;
			for (int k = 0; k < i; k++)
			{
				temp += L[i][k] * U[k][j];
			}
			U[i][j] = A[i][j] - temp;
			if (abs(U[i][j]) < epsilon)
			{
				U[i][j] = 0;
			}
		}
		//计算L(j行i列)
		for (int j = i; j < n; j++)
		{
			double temp = 0;
			for (int k = 0; k < i; k++)
			{
				temp += L[j][k] * U[k][i];
			}
			L[j][i] = 1.0 * (A[j][i] - temp) / U[i][i];
			if (abs(L[i][j]) < epsilon)
			{
				L[i][j] = 0;
			}
		}

	}

	//L U剩余位置设为0
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n; j++)
		{
			if (i > j)
			{
				U[i][j] = 0;
			}
			else if (i < j)
			{
				L[i][j] = 0;
			}
		}
	}

	//LU求逆
	//求矩阵U的逆 
	for (int i = 0; i < n; i++)
	{
		inv_U[i][i] = 1 / U[i][i];// U对角元素的值,直接取倒数
		for (int k = i - 1; k >= 0; k--)
		{
			double s = 0;
			for (int j = k + 1; j <= i; j++)
			{
				s = s + U[k][j] * inv_U[j][i];
			}
			inv_U[k][i] = -s / U[k][k];//迭代计算,按列倒序依次得到每一个值,
			if (abs(inv_U[k][i]) < epsilon)
			{
				inv_U[k][i] = 0;
			}
		}
	}

	//求矩阵L的逆
	for (int i = 0; i < n; i++)
	{
		inv_L[i][i] = 1; //L对角元素的值,直接取倒数,这里为1
		for (int k = i + 1; k < n; k++)
		{
			for (int j = i; j <= k - 1; j++)
			{
				inv_L[k][i] = inv_L[k][i] - L[k][j] * inv_L[j][i];
				if (abs(inv_L[k][i]) < epsilon)
				{
					inv_L[k][i] = 0;
				}
			}
		}
	}

	inv_A = Matrix_mul(inv_U, inv_L);
	return inv_A;
}

矩阵输出

vector<vector<double>> Output_Matrix(const vector<vector<double>>& A)//矩阵输出
{
    int l = A.size();
	int c = A[0].size();
	cout << endl;
for (int i = 0; i < l; i++)//输出矩阵 {
for (int j = 0; j < c; j++) { cout << A[i][j]; } cout << endl; } cout << endl;
}

整合后(有bug)

#include<iostream>
#include<conio.h>
#include<vector>
using namespace std;

char option;//选项
const double epsilon = 1e-12;//小于该数判断为0

vector<vector<double>> v;//矩阵

vector<vector<double>> Create_Matrix(int h, int l)//创建 h行l列的矩阵,并将初始各值设定为0
{
	for (int i = 0; i < h; i++)
	{
		vector<double>v1(l, 0);
		v.push_back(v1);
	}
	return v;
}

vector<vector<double>> Matrix_add(const vector<vector<double>>& A, const vector<vector<double>>& B)//矩阵相加
{
	int h = A.size();
	int l = A[0].size();

	vector<vector<double>> C;
	C = Create_Matrix(h, l);//创建矩阵C

	for (int i = 0; i < h; i++)
	{
		for (int j = 0; j < l; j++)
		{
			C[i][j] = A[i][j] + B[i][j];
			if (abs(C[i][j]) < epsilon)
			{
				C[i][j] = 0;
			}
		}
	}
	return C;
}

vector<vector<double>> Matrix_sub(const vector<vector<double>>& A, const vector<vector<double>>& B)//矩阵相减
{
	int h = A.size();
	int l = A[0].size();

	vector<vector<double>> C;
	C = Create_Matrix(h, l);//创建矩阵C

	for (int i = 0; i < h; i++)
	{
		for (int j = 0; j < l; j++)
		{
			C[i][j] = A[i][j] - B[i][j];
			if (abs(C[i][j]) < epsilon)
			{
				C[i][j] = 0;
			}
		}
	}
	return C;
}

vector<vector<double>> Matrix_mul(const vector<vector<double>>& A, const vector<vector<double>>& B)//矩阵相乘
{
	int A_h = A.size();
	int A_l = A[0].size();
	int B_h = B.size();
	int B_l = B[0].size();

	if (A_l != B_h)
	{
		cout << "两矩阵维数无法相乘" << endl;
		exit(0);
	}

	vector<vector<double>> C= Create_Matrix(A_h, B_l);//创建矩阵C
	for (int i = 0; i < A_h; i++)
	{
		for (int j = 0; j < B_l; j++)
		{
			C[i][j] = 0;
			for (int k = 0; k < A_l; k++)
			{
				C[i][j] += A[i][k] * B[k][j];
			}
			if (abs(C[i][j]) < epsilon)
			{
				C[i][j] = 0;
			}
		}
	}
	return C;
}

vector<vector<double>> Matrix_x_num(const vector<vector<double>>& A, double num)//数字乘矩阵
{
	int A_h = A.size();
	int A_l = A[0].size();

	vector<vector<double>> B = Create_Matrix(A_h, A_l);//创建矩阵B

	for (int i = 0; i < A_h; i++)
	{
		for (int j = 0; j < A_l; j++)
		{
			B[i][j] = num * A[i][j];
		}
	}
	return B;
}

vector<vector<double>> Superposition_on_matrix(const vector<vector<double>>& A, const vector<vector<double>>& B)//矩阵A与矩阵B上下叠加获得新的矩阵C,并返回
{
	//判断矩阵的列是否相等
	int A_h = A.size();
	int A_l = A[0].size();
	int B_h = B.size();
	int B_l = B[0].size();

	if (A_l != B_l)
	{
		cout << "叠加的矩阵列数不相等" << endl;
		exit(0);
	}

	//创建
	vector<vector<double>> C = Create_Matrix(A_h + B_h, A_l);

	//将A传入
	for (int i = 0; i < A_h; i++)
	{
		for (int j = 0; j < A_l; j++)
		{
			C[i][j] = A[i][j];
		}
	}

	//将B传入
	for (int i = 0; i < B_h; i++)
	{
		for (int j = 0; j < B_l; j++)
		{
			C[i + A_h][j] = B[i][j];
		}
	}
	return C;
}

vector<vector<double>> L_R_Superposition_matrix(const vector<vector<double>>& A, const vector<vector<double>>& B)//矩阵A与矩阵B左右叠加,获得新的矩阵C
{
	//判断矩阵的列是否相等
	int A_h = A.size();
	int A_l = A[0].size();
	int B_h = B.size();
	int B_l = B[0].size();

	if (A_h != B_h)
	{
		cout << "叠加的矩阵行数不相等" << endl;
		exit(0);
	}

	//创建叠加后的矩阵C
	vector<vector<double>> C = Create_Matrix(A_h, A_l + B_l);

	//将A传入
	for (int i = 0; i < A_h; i++)
	{
		for (int j = 0; j < A_l; j++)
		{
			C[i][j] = A[i][j];
		}
	}

	//将B传入
	for (int i = 0; i < B_h; i++)
	{
		for (int j = 0; j < B_l; j++)
		{
			C[i][j + A_l] = B[i][j];
		}
	}
	return C;
}

vector<vector<double>> Matrix_device(const vector<vector<double>>& A)//矩阵转置
{
	vector<vector<double>> AT = Create_Matrix(A[0].size(), A.size());//AT为转置矩阵
	int l = AT.size();
	int c = AT[0].size();
	for (int i = 0; i < l; i++)
	{
		for (int j = 0; j < c; j++)
		{
			AT[i][j] = A[j][i];
		}
	}
	return AT;
}

vector<vector<double>> Matrix_rotation(const vector<vector<double>>& A)//矩阵旋转
{
	int l = A.size();
	int c = A[0].size();
	//水平翻转
	for (int i = 0; i < l / 2; i++)
	{
		for (int j = 0; j < l; j++)
		{
			swap(A[i][j], A[l - i - 1][j]);//交换函数
		}
	}

	//对角线翻转
	for (int i = 0; i < l; i++)
	{
		for (int j = 0; j < i; j++)
		{
			swap(A[i][j], A[j][i]);
		}
	}
	return A;
}

vector<vector<double>> Matrix_inversion(const vector<vector<double>>& A)//矩阵求逆
{
	if (A.size() != A[0].size())
	{
		cout << "该矩阵无法求逆矩阵" << endl;
		exit(0);
	}
	int n = A.size();
	vector<vector<double>> inv_A = Create_Matrix(n, n);//逆矩阵
	vector<vector<double>> L = Create_Matrix(n, n);
	vector<vector<double>> U = Create_Matrix(n, n);
	vector<vector<double>> inv_L = Create_Matrix(n, n);
	vector<vector<double>> inv_U = Create_Matrix(n, n);//LU分解

	//L矩阵对角元素为1
	for (int i = 0; i < n; i++)
	{
		L[i][i] = 1;
	}

	//U矩阵第一行
	for (int i = 0; i < n; i++)
	{
		U[0][i] = A[0][i];
	}

	//L矩阵第一列
	for (int i = 0; i < n; i++)
	{
		U[0][i] = A[0][i];
	}

	//计算LU上下三角
	for (int i = 1; i < n; i++)
	{
		//计算U(i行j列)
		for (int j = i; j < n; j++)
		{
			double temp = 0;
			for (int k = 0; k < i; k++)
			{
				temp += L[i][k] * U[k][j];
			}
			U[i][j] = A[i][j] - temp;
			if (abs(U[i][j]) < epsilon)
			{
				U[i][j] = 0;
			}
		}
		//计算L(j行i列)
		for (int j = i; j < n; j++)
		{
			double temp = 0;
			for (int k = 0; k < i; k++)
			{
				temp += L[j][k] * U[k][i];
			}
			L[j][i] = 1.0 * (A[j][i] - temp) / U[i][i];
			if (abs(L[i][j]) < epsilon)
			{
				L[i][j] = 0;
			}
		}

	}

	//L U剩余位置设为0
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n; j++)
		{
			if (i > j)
			{
				U[i][j] = 0;
			}
			else if (i < j)
			{
				L[i][j] = 0;
			}
		}
	}

	//LU求逆
	//求矩阵U的逆 
	for (int i = 0; i < n; i++)
	{
		inv_U[i][i] = 1 / U[i][i];// U对角元素的值,直接取倒数
		for (int k = i - 1; k >= 0; k--)
		{
			double s = 0;
			for (int j = k + 1; j <= i; j++)
			{
				s = s + U[k][j] * inv_U[j][i];
			}
			inv_U[k][i] = -s / U[k][k];//迭代计算,按列倒序依次得到每一个值,
			if (abs(inv_U[k][i]) < epsilon)
			{
				inv_U[k][i] = 0;
			}
		}
	}

	//求矩阵L的逆
	for (int i = 0; i < n; i++)
	{
		inv_L[i][i] = 1; //L对角元素的值,直接取倒数,这里为1
		for (int k = i + 1; k < n; k++)
		{
			for (int j = i; j <= k - 1; j++)
			{
				inv_L[k][i] = inv_L[k][i] - L[k][j] * inv_L[j][i];
				if (abs(inv_L[k][i]) < epsilon)
				{
					inv_L[k][i] = 0;
				}
			}
		}
	}

	inv_A = Matrix_mul(inv_U, inv_L);
	return inv_A;
}

vector<vector<double>> Output_Matrix(const vector<vector<double>>& A)//矩阵输出
{
	cout << "\t是否输出矩阵" << endl;
	cout << "1.是" << endl;
	cout << "2.否" << endl;
	option = _getch();
	switch (option)
	{
	case '1':
	{
		int l = A.size();
		int c = A[0].size();
		cout << endl;
		for (int i = 0; i < l; i++)//输出矩阵
		{
			for (int j = 0; j < c; j++)
			{
				cout << A[i][j];
			}
			cout << endl;
		}
		cout << endl;
		break;
	}
	case '2':
		break;
	default:
		cout << "该选项不存在,请重新输入" << endl;
		break;
	}
}

int Matrix_Operations()//矩阵操作菜单
{
	cout << "\t请输入你的选项" << endl;
	cout << "1.矩阵相加" << endl;
	cout << "2.矩阵相减" << endl;
	cout << "3.矩阵相乘" << endl;
	cout << "4.数字乘矩阵" << endl;
	cout << "5.矩阵上叠加" << endl;
	cout << "6.矩阵左右叠加" << endl;
	cout << "7.矩阵转置" << endl;
	cout << "8.矩阵旋转" << endl;
	cout << "9.矩阵求逆" << endl;
	cout << "A.矩阵输出" << endl;
	cout << "B.创建矩阵\n" << endl;
	cout << "0.退出" << endl;
	option = _getch();
	switch (option)
	{
	case '1':
		Matrix_add(v, v);//矩阵相加
		break;
	case '2':
		Matrix_sub(v, v);//矩阵相减
		break;
	case '3':
		Matrix_mul(v, v);//矩阵相乘
	case '4':
		cout << "请输入数字" << endl;
		float num;
		cin >> num;
		Matrix_x_num(v, num);//数字乘矩阵
		break;
	case '5':
		Superposition_on_matrix(v, v);//矩阵上叠加
		break;
	case '6':
		L_R_Superposition_matrix(v, v);//矩阵左右叠加
		break;
	case '7':
		Matrix_device(v);//矩阵转置
		break;
	case '8':
		Matrix_rotation(v);//矩阵旋转
		break;
	case '9':
		Matrix_inversion(v);//矩阵求逆
		break;
	case 'A':
		Output_Matrix(v);//矩阵输出
		break;
	case 'B':
		cout << "请输入矩阵的行和列" << endl;
		int h, l;
		cin >> h >> l;
		Create_Matrix(h, l);//创建矩阵
		break;
	case '0':
		exit(0);
		break;
	default:
		cout << "该选项不存在,请重新输入" << endl;
		break;
	}
}

int main()
{
	while (1)
	{
		Matrix_Operations();//菜单界面
	}
	return 0;
}