vs2022 mn矩阵运算 加减乘除

开始--vs2022--右键--打开文件所在位置--找到快捷方式--复制到桌面--

vs2022--工具--主题--深色--

vs2022菜单栏--项目--添加新项--C++文件(.cpp)--main.cpp、Matrix.cpp

头文件(.h)--Matrix.h

一、加法

Matrix.h

cpp 复制代码
#pragma once
#include <vector>//std::vector
#include <iostream>//invalid_argument
#include <iomanip>//setw

class Matrix {
private:
    std::vector<std::vector<double>> data;
    int rows;  // 行数 m
    int cols;  // 列数 n

public:
    

    // 构造函数
    Matrix(int m, int n);
    Matrix(const std::vector<std::vector<double>>& mat);

    // 获取矩阵维度
    int getRows() const { return rows; }
    int getCols() const { return cols; }

    // 访问元素
    ;//&返回应用,可以修改元素值result(i, j)
    double& operator()(int i, int j);
    //返回值,不能修改other(i, j)
    double operator()(int i, int j) const;

    // 基本运算(要求维度匹配)
    Matrix operator + (const Matrix& other) const;

    void print() const;
};

Matrix.cpp

cpp 复制代码
#include "Matrix.h"


// ===========构造函数===============
;//第一个Matrix返回类型;第二个Matrix函数名
//用m初始化rows,用n初始化cols
Matrix::Matrix(int m, int n) : rows(m),cols(n)
{
    //将data调整为rows行,
    ;//每行都是std::vector<double>(cols, 0.0)
    ;//每个元素都是0.0
    data.resize(rows, std::vector<double>(cols, 0.0));
}

Matrix::Matrix(const std::vector<std::vector<double>>& mat)
{
    //static_cast<int>()显式转换,消除size_t转int警告
    rows = static_cast<int>(mat.size());//获取矩阵的行数、列数size
    if (rows > 0)
    {
        cols = static_cast<int>(mat[0].size());
    }
    else 
    {
        cols = 0;
    }
    data = mat;//拷贝整个矩阵mat到data
}

// =======元素访问============
double& Matrix::operator()(int i, int j)
{
    if (i < 0 || i >= rows || j < 0 || j >= cols)
    {
        throw std::out_of_range("索引超出范围");
    }   
    return data[i][j];
}

double Matrix::operator()(int i, int j) const
{
    if (i < 0 || i >= rows || j < 0 || j >= cols)
    {
        throw std::out_of_range("索引超出范围");
    }
    return data[i][j];
}

// =============矩阵加法=================
Matrix Matrix::operator + (const Matrix& other) const
{
    if (rows != other.rows || cols != other.cols)
    {
        //invalid_argument标准库中的异常类
        ;//std:C++ 标准库命名空间
        throw std::invalid_argument("矩阵维度不匹配:加法要求行列数相同");
    }
    Matrix result(rows, cols);//定义result并且初始化
    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < cols; j++)
        {
            result(i, j) = data[i][j] + other(i, j);
        }
    }
    return result;//返回result
}

// 打印矩阵
void Matrix::print() const
{
    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < cols; j++)
        {
            std::cout << std::setw(10);//设置输入宽度10
            std::cout << std::fixed;//设置固定小数点
            std::cout << std::setprecision(4); //设置精度4位小数
            std::cout << data[i][j];//输出数值
        }
        std::cout << std::endl;//换行
    }
}

Main.cpp

cpp 复制代码
#include "Matrix.h"

int main() {
    try {
        std::cout << "=== m×n 矩阵运算测试程序 ===" << std::endl;

        // ========== 1. 创建不同维度的矩阵 ==========
        std::cout << "\n【1】创建不同维度的矩阵" << std::endl;

        // 2×3 矩阵
        std::vector<std::vector<double>> aData = 
        {
            {1, 2, 3},
            {4, 5, 6}
        };
        Matrix A(aData);
        std::cout << "\n矩阵 A (2×3):" << std::endl;
        A.print();

        // 2×3 矩阵
        std::vector<std::vector<double>> bData =
        {
            {7,  8,  9},
            {10, 11, 12}
        };
        Matrix B(bData);
        std::cout << "\n矩阵 B (2×3):" << std::endl;
        B.print();

        // ========== 2. 矩阵加法(要求维度相同)==========
        std::cout << "\n【2】矩阵加法 (2×3 + 2×3)" << std::endl;
        std::cout << "A + B:" << std::endl;
        (A + B).print();
    }
    catch (const std::exception& e) 
    {
        std::cout << "错误: " << e.what() << std::endl;
    }
    return 0;
}

键盘--F5--结果如下图--

二、加减乘除

Matrix.h

cpp 复制代码
#pragma once
#include <vector>//std::vector
#include <iostream>//invalid_argument
#include <iomanip>//setw

//Matrix矩阵
class Matrix {
private:
    std::vector<std::vector<double>> data;
    int rows;  // 行数 m
    int cols;  // 列数 n

public:
    

    // 构造函数
    Matrix(int m, int n);
    Matrix(const std::vector<std::vector<double>>& mat);

    // 获取矩阵维度
    int getRows() const { return rows; }
    int getCols() const { return cols; }

    // 访问元素
    ;// &返回应用,可以修改元素值result(i, j)
    double& operator()(int i, int j);
    // 返回值,不能修改other(i, j)
    double operator()(int i, int j) const;

    // 基本运算(要求维度匹配)
    Matrix operator + (const Matrix& other) const;
    Matrix operator - (const Matrix& other) const;
    Matrix operator * (const Matrix& other) const;  // 矩阵乘法
    Matrix operator * (double scalar) const;        // 标量乘法
    Matrix operator / (const Matrix& other) const;  // 左除 BX=A
    Matrix rightDivide(const Matrix& other) const;  // 右除 XB=A

    // 计算行列式
    bool isSquare() const { return rows == cols; } // 检查是否为方阵:1是0否
    Matrix minor(int row, int col) const; // 删除第row行和第col列的子式
    double cofactor(int row, int col) const; // 计算余子式
    double determinant() const; // 计算行列式
    
    // 矩阵求逆
    Matrix inverse() const; // 矩阵的逆
    Matrix adjoint() const; // 余子式的转置

    // 矩阵操作
    Matrix transpose() const; // 转置
    Matrix submatrix(int r1, int r2, int c1, int c2) const; // 获取子矩阵r1*c1到r2*c2

    // 工具函数
    void setIdentity(); // 生成(In,0)
    void setZero();     // 生成(0,0)
    void print() const; // 打印矩阵

};

// 标量乘法(友元函数)
Matrix operator * (double scalar, const Matrix& mat);

Matrix.cpp

cpp 复制代码
#include "Matrix.h"


// ===========构造函数===============
;//第一个Matrix返回类型;第二个Matrix函数名
//用m初始化rows,用n初始化cols
Matrix::Matrix(int m, int n) : rows(m),cols(n)
{
    //将data调整为rows行,
    ;//每行都是std::vector<double>(cols, 0.0)
    ;//每个元素都是0.0
    data.resize(rows, std::vector<double>(cols, 0.0));
}

Matrix::Matrix(const std::vector<std::vector<double>>& mat)
{
    //static_cast<int>()显式转换,消除size_t转int警告
    rows = static_cast<int>(mat.size());//获取矩阵的行数、列数size
    if (rows > 0)
    {
        cols = static_cast<int>(mat[0].size());
    }
    else 
    {
        cols = 0;
    }
    data = mat;//拷贝整个矩阵mat到data
}

// =======元素访问============
double& Matrix::operator()(int i, int j)
{
    if (i < 0 || i >= rows || j < 0 || j >= cols)
    {
        throw std::out_of_range("索引超出范围");
    }   
    return data[i][j];
}

double Matrix::operator()(int i, int j) const
{
    if (i < 0 || i >= rows || j < 0 || j >= cols)
    {
        throw std::out_of_range("索引超出范围");
    }
    return data[i][j];
}

// =============矩阵加法=================
Matrix Matrix::operator + (const Matrix& other) const
{
    if (rows != other.rows || cols != other.cols)
    {
        //invalid_argument标准库中的异常类
        ;//std:C++ 标准库命名空间
        throw std::invalid_argument("矩阵维度不匹配:加法要求行列数相同");
    }
    Matrix result(rows, cols);//定义result并且初始化
    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < cols; j++)
        {
            result(i, j) = data[i][j] + other(i, j);
        }
    }
    return result;//返回result
}

// =============矩阵减法=================
Matrix Matrix::operator - (const Matrix& other) const
{
    if (rows != other.rows || cols != other.cols)
    {
        //invalid_argument标准库中的异常类
        ;//std:C++ 标准库命名空间
        throw std::invalid_argument("矩阵维度不匹配:减法要求行列数相同");
    }
    Matrix result(rows, cols);//定义result并且初始化
    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < cols; j++)
        {
            result(i, j) = data[i][j] - other(i, j);
        }
    }
    return result;//返回result
}

// ========== 矩阵乘法 ==========
Matrix Matrix::operator * (const Matrix& other) const
{
    if (cols != other.rows)
    {
        throw std::invalid_argument("矩阵维度不匹配:乘法要求左矩阵列数等于右矩阵行数");
    }
    Matrix result(rows, other.cols);

    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < other.cols; j++)
        {
            double sum = 0;
            for (int k = 0; k < cols; k++)
            {
                sum += data[i][k] * other(k, j);
            }
            result(i, j) = sum;
        }
    }
    return result;
}

// ========== 标量乘法 ==========
Matrix Matrix::operator * (double scalar) const
{
    Matrix result(rows, cols);
    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < cols; j++)
        {
            result(i, j) = data[i][j] * scalar;
        }
    }
    return result;
}

// ========== 除法运算(仅对方阵有效)==========
Matrix Matrix::operator / (const Matrix& other) const // 左除 BX=A
{
    if (!other.isSquare())
    {
        throw std::runtime_error("除法:除数矩阵必须是方阵");
    }
    Matrix invOther = other.inverse(); // 矩阵的逆
    return invOther * (*this); // (*this) 当前对象
}

Matrix Matrix::rightDivide(const Matrix& other) const // 右除 XB=A
{
    if (!other.isSquare())
    {
        throw std::runtime_error("除法:除数矩阵必须是方阵");
    }
    Matrix invOther = other.inverse();
    return (*this) * invOther; // (*this) 当前对象
}

// 计算行列式
double Matrix::determinant() const 
{
    if ( !isSquare() )// 检查是否为方阵:1是0否
    {
        throw std::runtime_error("行列式只能计算方阵");
    }
    int n = rows;
    if (n == 1)
    {
        return data[0][0];
    }
    if (n == 2)
    {
        return data[0][0] * data[1][1] - data[0][1] * data[1][0];
    }
    double det = 0;
    for (int j = 0; j < n; j++)
    {
        det += data[0][j] * cofactor(0, j);//a11*A11+...+a1n*A1n
    }
    return det;
}

double Matrix::cofactor(int row, int col) const // 计算余子式
{
    if (!isSquare())// 检查是否为方阵:1是0否
    {
        throw std::runtime_error("余子式只能计算方阵");
    }

    // 如果行号+列号是偶数,符号为正(+1);奇数则符号为负(-1)
    int sign;

    if ((row + col) % 2 == 0)
    {
        sign = 1;   // 正号
    }
    else
    {
        sign = -1;  // 负号
    }

    // 计算子矩阵(删除第row行第col列)
    Matrix subMatrix = minor(row, col);

    // 计算子矩阵的行列式值
    double minorDeterminant = subMatrix.determinant();

    // 返回余子式 = 符号 × 子式的行列式
    return sign * minorDeterminant;
}

Matrix Matrix::minor(int row, int col) const//删除第row行和第col列的子式
{
    if (!isSquare())// 检查是否为方阵:1是0否
    {
        throw std::runtime_error("子式只能计算方阵");
    }

    int n = rows;
    Matrix minorMat(n - 1, n - 1);
    int mi = 0, mj;

    for (int i = 0; i < n; i++) 
    {
        if (i == row)
        {
            continue;// 跳过本次循环的后续代码
        }

        mj = 0;
        for (int j = 0; j < n; j++) 
        {
            if (j == col)
            {
                continue;// 跳过本次循环的后续代码
            }
            minorMat(mi, mj) = data[i][j];
            mj++;
        }
        mi++;
    }

    return minorMat;
}

Matrix Matrix::inverse() const // 矩阵的逆
{
    if (!isSquare()) // 检查是否为方阵:1是0否
    {
        throw std::runtime_error("逆矩阵只能计算方阵");
    }

    double det = determinant(); // 计算行列式
    if (std::abs(det) < 1e-10)
    {
        throw std::runtime_error("矩阵不可逆,行列式为0");
    }

    Matrix adj = adjoint();  // 余子式的转置
    Matrix inv(rows, cols);

    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < cols; j++)
        {
            inv(i, j) = adj(i, j) / det;
        }
    }

    return inv;
}

Matrix Matrix::adjoint() const  // 余子式的转置
{
    if (!isSquare()) // 检查是否为方阵:1是0否
    {
        throw std::runtime_error("伴随矩阵只能计算方阵");
    }

    int n = rows;
    Matrix adj(n, n);

    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            adj(j, i) = cofactor(i, j);  // 余子式的转置
        }
    }

    return adj;
}

// ========== 矩阵转置 ==========
Matrix Matrix::transpose() const
{
    Matrix result(cols, rows);

    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < cols; j++)
        {
            result(j, i) = data[i][j];
        }    
    }

    return result;
}

// ========== 获取子矩阵 r1*c1到r2*c2==========
Matrix Matrix::submatrix(int r1, int r2, int c1, int c2) const
{
    if (r1 < 0 || r2 >= rows || r1 > r2 || c1 < 0 || c2 >= cols || c1 > c2)
    {
        throw std::invalid_argument("子矩阵索引无效");
    }

    int newRows = r2 - r1 + 1;
    int newCols = c2 - c1 + 1;
    Matrix result(newRows, newCols);

    for (int i = r1; i <= r2; i++)
    {
        for (int j = c1; j <= c2; j++)
        {
            result(i - r1, j - c1) = data[i][j];
        } 
    }

    return result;
}

// ========== 工具函数 ==========
void Matrix::setIdentity() // 生成(In,0)
{
    if (!isSquare())
    {
        throw std::runtime_error("单位矩阵只能设置方阵");
    }

    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < cols; j++)
        {
            data[i][j] = (i == j) ? 1.0 : 0.0;
        }
    }        
}

void Matrix::setZero() // 生成(0,0)
{
    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < cols; j++)
        {
            data[i][j] = 0.0;
        }   
    }
}

// 打印矩阵
void Matrix::print() const
{
    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < cols; j++)
        {
            std::cout << std::setw(10);//设置输入宽度10
            std::cout << std::fixed;//设置固定小数点
            std::cout << std::setprecision(4); //设置精度4位小数
            std::cout << data[i][j];//输出数值
        }
        std::cout << std::endl;//换行
    }
}

// 标量乘法(友元函数)
Matrix operator * (double scalar, const Matrix& mat)
{
    return mat * scalar;
}

Main.cpp

cpp 复制代码
#include "Matrix.h"

int main()
{
    try {
        std::cout << "=== m×n 矩阵运算测试程序 ===" << std::endl;

        // ========== 1. 创建不同维度的矩阵 ==========
        std::cout << "\n【1】创建不同维度的矩阵" << std::endl;

        // 2×3 矩阵
        std::vector<std::vector<double>> aData = 
        {
            {1, 2, 3},
            {4, 5, 6}
        };
        Matrix A(aData);
        std::cout << "\n矩阵 A (2×3):" << std::endl;
        A.print();

        // 3×2 矩阵
        std::vector<std::vector<double>> bData = {
            {7, 8},
            {9, 10},
            {11, 12}
        };
        Matrix B(bData);
        std::cout << "\n矩阵 B (3×2):" << std::endl;
        B.print();

        // 2×2 方阵
        std::vector<std::vector<double>> cData = {
            {1, 2},
            {3, 4}
        };
        Matrix C(cData);
        std::cout << "\n矩阵 C (2×2 方阵):" << std::endl;
        C.print();

        // 2×2 方阵
        std::vector<std::vector<double>> dData = {
            {5, 6},
            {7, 8}
        };
        Matrix D(dData);
        std::cout << "\n矩阵 D (2×2 方阵):" << std::endl;
        D.print();

        // ========== 2. 矩阵加法(要求维度相同)==========
        std::cout << "\n【2】矩阵加法 (2×3 + 2×3)" << std::endl;
        // 创建另一个 2×3 矩阵
        std::vector<std::vector<double>> eData = {
            {7, 8, 9},
            {10, 11, 12}
        };
        Matrix E(eData);
        std::cout << "A + E:" << std::endl;
        (A + E).print();

        // ========== 3. 矩阵乘法 ==========
        std::cout << "\n【3】矩阵乘法" << std::endl;
        std::cout << "A (2×3) × B (3×2) = (2×2):" << std::endl;
        Matrix AB = A * B;
        AB.print();

        std::cout << "\nC (2×2) × D (2×2) = (2×2):" << std::endl;
        (C * D).print();

        // ========== 4. 标量乘法 ==========
        std::cout << "\n【4】标量乘法" << std::endl;
        std::cout << "2 × A:" << std::endl;
        (2.0 * A).print();

        // ========== 5. 除法运算(仅对方阵)==========
        std::cout << "\n【5】除法运算 (仅对方阵有效)" << std::endl;
        std::cout << "左除: C / D = D^{-1} × C" << std::endl;
        (C / D).print();

        std::cout << "\n右除: C / D = C × D^{-1}" << std::endl;
        C.rightDivide(D).print();

        // ========== 6. 方阵运算 ==========
        std::cout << "\n【6】方阵运算" << std::endl;
        std::cout << "C 的行列式: " << C.determinant() << std::endl;

        std::cout << "\nC 的逆矩阵:" << std::endl;
        Matrix C_inv = C.inverse();
        C_inv.print();

        std::cout << "\n验证: C × C^{-1} (应为单位矩阵):" << std::endl;
        (C * C_inv).print();

        // ========== 7. 矩阵转置 ==========
        std::cout << "\n【7】矩阵转置" << std::endl;
        std::cout << "A 的转置 (3×2):" << std::endl;
        A.transpose().print();

        // ========== 8. 子矩阵提取 ==========
        std::cout << "\n【8】子矩阵提取 (从 3×4 矩阵中提取)" << std::endl;
        std::vector<std::vector<double>> fData = {
            {1, 2, 3, 4},
            {5, 6, 7, 8},
            {9, 10, 11, 12}
        };
        Matrix F(fData);
        std::cout << "原矩阵 F (3×4):" << std::endl;
        F.print();

        std::cout << "\n提取子矩阵 (行0-1, 列1-2):" << std::endl;
        F.submatrix(0, 1, 1, 2).print();

        // ========== 9. 错误处理演示 ==========
        std::cout << "\n【9】错误处理演示" << std::endl;
        try 
        {
            std::cout << "尝试计算非方阵的行列式..." << std::endl;
            A.determinant();  // 这会抛出异常
        }
        catch (const std::exception& e) 
        {
            std::cout << "错误: " << e.what() << std::endl;
        }

        try
        {
            std::cout << "\n尝试维度不匹配的加法..." << std::endl;
            (A + C).print();  // A是2×3,C是2×2,维度不同
        }
        catch (const std::exception& e)
        {
            std::cout << "错误: " << e.what() << std::endl;
        }
    }
    catch (const std::exception& e) // 捕获标准异常
    {
        std::cout << "错误: " << e.what() << std::endl;
    }

    return 0;
}
相关推荐
sin°θ_陈2 小时前
前馈式3D Gaussian Splatting 研究地图(总览篇):解构七大路线,梳理方法谱系,看懂关键分歧与未来趋势
论文阅读·深度学习·算法·3d·aigc·空间计算·3dgs
泡泡茶壶Wending2 小时前
OPENGL之摄像机与视图变换矩阵
线性代数·矩阵
阿Y加油吧2 小时前
LeetCode 双指针经典双题解|盛最多水的容器 + 三数之和,从入门到进阶吃透套路
算法·leetcode·职场和发展
励志的小陈2 小时前
C++入门
开发语言·c++
繁星星繁2 小时前
Python基础语法(一)
c++·笔记·python
进击的荆棘2 小时前
C++起始之路——继承
开发语言·c++
B站_计算机毕业设计之家2 小时前
计算机毕业设计:汽车数据可视化与后台管理平台 Django框架 requests爬虫 可视化 车辆 数据分析 大数据 机器学习(建议收藏)✅
python·算法·机器学习·信息可视化·django·汽车·课程设计
格林威2 小时前
工业相机图像采集处理:从 RAW 数据到 AI 可读图像,堡盟相机 C#实战代码深度解析
c++·人工智能·数码相机·opencv·算法·计算机视觉·c#
lvxiangyu1111 小时前
MPPI 算法证明重构:基于无穷维泛函变分与 KL 散度的构造性推导
算法·重构·最优控制·随机最优控制