如何不使用vector与template实现矩阵加减乘转置等运算?
不用vector和template实现矩阵运算的方案
嘿,这个问题问得实在!既然你之前靠vector和template搞定过矩阵运算,那咱们换个接地气的思路——手动管理内存+针对具体数据类型来实现,完全不用那俩工具也能把加减乘转置这些操作搞定。我用C++给你一步步拆解:
1. 先定义矩阵的基础结构
首先得用一个结构体来封装矩阵的核心信息:行数、列数,还有存数据的内存空间。咱们用动态分配的二维数组来存数据(毕竟静态数组没法灵活适配不同大小的矩阵):
#include <iostream> using namespace std; // 定义矩阵结构体 struct Matrix { int rows; int cols; double** data; // 用double类型举例,你也换成int/float都行 };
2. 矩阵的创建与销毁
因为是手动分配内存,所以必须写专门的函数来创建和销毁矩阵,避免内存泄漏:
// 创建一个空矩阵,分配内存 Matrix createMatrix(int rows, int cols) { Matrix mat; mat.rows = rows; mat.cols = cols; // 先分配行指针 mat.data = new double*[rows]; // 再给每行分配列空间 for (int i = 0; i < rows; i++) { mat.data[i] = new double[cols](); // 括号里的()会把元素初始化为0 } return mat; } // 销毁矩阵,释放内存 void destroyMatrix(Matrix& mat) { // 先释放每行的内存 for (int i = 0; i < mat.rows; i++) { delete[] mat.data[i]; } // 再释放行指针数组 delete[] mat.data; // 重置成员,避免野指针 mat.rows = 0; mat.cols = 0; mat.data = nullptr; }
3. 逐个实现矩阵运算
接下来就是核心的运算函数了,每个函数都先做合法性检查,再执行运算:
3.1 矩阵加法
要求:两个矩阵的行数、列数必须完全相同
Matrix addMatrices(const Matrix& mat1, const Matrix& mat2) { // 先检查合法性 if (mat1.rows != mat2.rows || mat1.cols != mat2.cols) { cerr << "Error: 矩阵行列数不匹配,无法相加!" << endl; return createMatrix(0, 0); // 返回空矩阵 } Matrix result = createMatrix(mat1.rows, mat1.cols); // 遍历每个元素相加 for (int i = 0; i < mat1.rows; i++) { for (int j = 0; j < mat1.cols; j++) { result.data[i][j] = mat1.data[i][j] + mat2.data[i][j]; } } return result; }
3.2 矩阵减法
逻辑和加法几乎一样,只是把加号换成减号:
Matrix subtractMatrices(const Matrix& mat1, const Matrix& mat2) { if (mat1.rows != mat2.rows || mat1.cols != mat2.cols) { cerr << "Error: 矩阵行列数不匹配,无法相减!" << endl; return createMatrix(0, 0); } Matrix result = createMatrix(mat1.rows, mat1.cols); for (int i = 0; i < mat1.rows; i++) { for (int j = 0; j < mat1.cols; j++) { result.data[i][j] = mat1.data[i][j] - mat2.data[i][j]; } } return result; }
3.3 矩阵乘法
要求:第一个矩阵的列数必须等于第二个矩阵的行数
Matrix multiplyMatrices(const Matrix& mat1, const Matrix& mat2) { if (mat1.cols != mat2.rows) { cerr << "Error: 第一个矩阵的列数不等于第二个矩阵的行数,无法相乘!" << endl; return createMatrix(0, 0); } // 结果矩阵的行数是mat1的行,列数是mat2的列 Matrix result = createMatrix(mat1.rows, mat2.cols); // 三重循环计算每个元素 for (int i = 0; i < mat1.rows; i++) { for (int j = 0; j < mat2.cols; j++) { double sum = 0; for (int k = 0; k < mat1.cols; k++) { sum += mat1.data[i][k] * mat2.data[k][j]; } result.data[i][j] = sum; } } return result; }
3.4 矩阵转置
转置就是把原矩阵的行和列互换,结果矩阵的行数是原矩阵的列,列数是原矩阵的行:
Matrix transposeMatrix(const Matrix& mat) { Matrix result = createMatrix(mat.cols, mat.rows); for (int i = 0; i < mat.rows; i++) { for (int j = 0; j < mat.cols; j++) { result.data[j][i] = mat.data[i][j]; } } return result; }
4. 测试示例
最后写个main函数来测试这些功能,看看实际效果:
// 辅助函数:打印矩阵 void printMatrix(const Matrix& mat) { for (int i = 0; i < mat.rows; i++) { for (int j = 0; j < mat.cols; j++) { cout << mat.data[i][j] << " "; } cout << endl; } } int main() { // 创建两个测试矩阵 Matrix mat1 = createMatrix(2, 2); mat1.data[0][0] = 1; mat1.data[0][1] = 2; mat1.data[1][0] = 3; mat1.data[1][1] = 4; Matrix mat2 = createMatrix(2, 2); mat2.data[0][0] = 5; mat2.data[0][1] = 6; mat2.data[1][0] = 7; mat2.data[1][1] = 8; // 测试加法 cout << "矩阵加法结果:" << endl; Matrix addResult = addMatrices(mat1, mat2); printMatrix(addResult); // 测试乘法 cout << "\n矩阵乘法结果:" << endl; Matrix mulResult = multiplyMatrices(mat1, mat2); printMatrix(mulResult); // 测试转置 cout << "\nmat1转置结果:" << endl; Matrix transResult = transposeMatrix(mat1); printMatrix(transResult); // 别忘了销毁所有矩阵,释放内存! destroyMatrix(mat1); destroyMatrix(mat2); destroyMatrix(addResult); destroyMatrix(mulResult); destroyMatrix(transResult); return 0; }
几个关键注意点
- 内存管理:一定要记得用完矩阵后调用
destroyMatrix,不然会造成内存泄漏; - 数据类型:我这里用了
double,你要是需要int或者float,直接把结构体里的double**换成对应的类型就行; - 错误处理:每个运算前都加了合法性检查,避免程序崩溃,你还可以根据需求扩展更详细的错误提示。
内容的提问来源于stack exchange,提问作者Mostafa Anwar
相关产品推荐
相关产品推荐

