只是测了下int型没问题,还有个卷积运算没做之后补上,给某个学生党做的,做的比较快。

#pragma once
#include <iostream>
#include <string>
#include <vector>
#include "..\utils\FileOperation.h"
#include "..\utils\Utils.h"
#include <sstream>
using namespace std;#define  MinSize 1                             //控制行列最小值
#define  MaxSize 500                           //控制行列最大值template <class T>
class CMat;template<class T>
class CMat
{template <class U>friend CMat<U> operator*(CMat<U>&,CMat<U>&); //矩阵乘法public://---------------构造CMat<T>() = delete;                         //删除默认构造函数CMat<T>(int r, int c, T value);             //指定行数r、列数c构造初始值均为value的矩阵CMat<T>(int r, int c, T* arr);              //给定一维数组arr,构建r行、c列矩阵CMat<T>(int r, int c);                      //创建构建r行、c列矩阵,矩阵值从键盘中输入//---------------析构virtual ~CMat();                            //析构函数//---------------拷贝构造(deep copy)CMat<T>(CMat<T>&);//---------------方法void printMat() const;                      //按矩阵行列格式打印矩阵void saveMat(const char *filename);         //保存矩阵数据到文件void loadMat(const char *filename);         //从文件中读取数据到矩阵int  getRows() const;                       //读取矩阵的行数int  getCols() const;                       //读取矩阵的列数bool isSquare() const;                      //判断是否为方阵void reSize(int p, int q);                  //将矩阵形状变换为p行、q列CMat<T> fetchRow(int row);                  //取给定行所有元素 row col从0开始取CMat<T> fetchCol(int col);                  //取给定列所有元素 row col从0开始取void swapRows(int a, int b);                //交换矩阵第a行和第b行元素的值 row col从0开始取void swapCols(int a, int b);                //交换矩阵第a列和第b列元素的值row col从0开始取static CMat<T> createEyeMat(int n);         //创建一个行数列数均为n的单位矩阵void detMat();                             //求矩阵行列式CMat<T>convMat(CMat<T>a, CMat<T>b);        //矩阵卷积运算//---------------重载                           T operator()(int row, int col);            //按给定的行和列取元素 row col从0开始取CMat<T>&operator+(CMat<T>&);               //矩阵加法CMat<T>&operator-(CMat<T>&);               //矩阵减法CMat<T>&operator=(CMat<T>&);               //矩阵深度复制bool operator==(CMat<T>&);                 //判断矩阵相等bool operator!=(CMat<T>&);                 //判断矩阵不相等private:int row;                                   //行int col;                                   //列T*  data;                                  //指向数据的一维指针
};template<class T>
void CMat<T>::printMat() const
{cout<<"当前实例矩阵为:\n";cout << "-------------------\n";for(int i = 0; i < row; i++){for (int j = 0; j < col; j++){cout<<*(data + i*col + j);if (j < col - 1){cout << "    ";}else if(j==col-1){cout <<"\n";}}}cout << "-------------------\n";
}template<class T>
void CMat<T>::saveMat(const char *filename)
{//文件格式: 1   21  21//          12  23  32     //          12  23  11 //          23  12  33string write_str = "";for (int i = 0; i < row; i++){for (int j = 0; j < col; j++){//string cur_str=atioif (write_str == ""){write_str += to_string(*(data + i*col + j));}else{if (j == col - 1){   //每行的最后一个加换行符write_str += " ";write_str += to_string(*(data + i*col + j));write_str += "\n";}else if (j == 0){//每行的第一个什么都不加write_str += to_string(*(data + i*col + j));}else{//中间段 加空格即可write_str += " ";write_str += to_string(*(data + i*col + j));}}}}//删除结尾的\nwrite_str.pop_back();//暂时不考虑中文编码问题-有需求再加//if (!FileOperation::IsFileExist(filename))/不考虑不存在//{//    return;//}//删除旧的bool delete_ret = FileOperation::GetFileOperation()->DeleteFile(filename);//如果没有 创建一个 然后直接写入bool create_ret = FileOperation::GetFileOperation()->CreateFile(write_str, filename);//失败情况不考虑
}template<class T>
void CMat<T>::loadMat(const char *filename)
{//cout<<"开始读取"<< endl;string read_str;if (!FileOperation::GetFileOperation()->IsFileExist(filename)) //不考虑不存在{cout << "读取的文件路径不存在:" << filename << endl;return;}else{bool read_ret = FileOperation::GetFileOperation()->ReadStringFromFile(filename, read_str);}//将字符串分割获取每一行vector<string>all_row_vec;SplitString(read_str, all_row_vec, "\n");if (all_row_vec.size() <= 0){cout << "读取文件失败" << filename << endl;}this->row = static_cast<int>(all_row_vec.size());cout << "文件矩阵行数" << to_string(row) << endl;//先取第一行列数 来构造datavector<string>first_row_vec;SplitString(all_row_vec[0], first_row_vec, " ");if (first_row_vec.size() <= 0){cout << "读取文件失败" << filename << endl;return;}//去第一行分割的列数 赋值给当前类this->col = static_cast<int>(first_row_vec.size());cout << "文件矩阵列数" << to_string(col) << endl;//构造datadata = new T[col*row];//以下语句赋值有崩溃风险 必须保证文件存取一定要正确for (int i = 0; i < all_row_vec.size(); i++){vector<string>one_row_vec;SplitString(all_row_vec[i], one_row_vec, " ");for (int j = 0; j < col; j++){istringstream iss(one_row_vec[j]);T num;iss >> num;*(data + i*col + j) = num;}}//cout << "结束读取,读取成功" << endl;
}template<class T>
int CMat<T>::getRows() const
{cout << "当前矩阵行数 " << to_string(row) << endl;return row;
}template<class T>
int CMat<T>::getCols() const
{cout << "当前矩阵列数 " << to_string(col) << endl;return col;
}template<class T>
bool CMat<T>::isSquare() const
{if (col == row){cout << "当前矩阵是方阵" << endl;return true;}else{cout << "当前矩阵不是方阵" << endl;return false;}
}template<class T>
void CMat<T>::reSize(int p, int q)
{//p*q必须和当前矩阵row*col一样if (p*q != row*col){//不符合条件取消return;}//符合条件,进行变换//直接将row和col用p q赋值即可this->row = p;this->col = q;
}template<class T>
T CMat<T>::operator()(int row, int col)
{if (row < 0 || row >= this->row || col < 0 || col >= this->col){cout << "重载()输入超出范围" << endl;}T cur_value = *(data + row*(this->col) + col);cout << "该矩阵第" << to_string(row) << "行,第" << to_string(col) << "列值为:" << to_string(cur_value) << endl;return cur_value;
}template<class T>
CMat<T>& CMat<T>::operator+(CMat<T>&mat)
{//判断是不是同型的矩阵int target_row = mat.getRows();int target_col = mat.getCols();if (target_row != this->row || target_row != this->col){cout << "不同型矩阵不能相加" << endl;}//数据部分不判断了T*target_data = mat.data;//相加for (int i = 0; i < row; i++){for (int j = 0; j < col; j++){T target_value = *(target_data + i*row + j);T cur_value = *(this->data + i*row + j);*(this->data + i*row + j) = cur_value + target_value;}}return *this;
}template<class T>
CMat<T>& CMat<T>::operator-(CMat<T>&mat)
{   //判断是不是同型的矩阵int target_row = mat.getRows();int target_col = mat.getCols();if (target_row != this->row || target_row != this->col){cout <<"不同型矩阵不能相减"<<endl;}//数据部分不判断了T*target_data = mat.data;//相加for (int i = 0; i < row; i++){for (int j = 0; j < col; j++){T target_value = *(target_data + i*row + j);T cur_value = *(this->data + i*row + j);*(this->data + i*row + j) = cur_value - target_value;}}return *this;
}template<class T>
CMat<T> CMat<T>::convMat(CMat<T>a, CMat<T>b)
{}template<class T>
void CMat<T>::detMat()
{}template<class T>
CMat<T> CMat<T>::createEyeMat(int n)
{T*data = new T[n*n];for (int i = 0; i < n*n; i++){*(data + i) = 1;}static CMat<T>result_mat(n, n, data);return result_mat;
}template<class T>
void CMat<T>::swapCols(int a, int b)
{//判断if(a <0||a>= col||b<0||b>=col){//参数不符合条件return;}//new一个暂存的数据 存下b列的数据 有row项T*temp_data = new T[row];for(int i= 0;i<row;i++){//将b列数据给到temp_data,b列数据用a列数据赋值,a列数据用temp_data赋值*(temp_data + i) = *(data + i*col+b);*(data + i*col +b) = *(data + i*col +a);*(data + i*col + a) = *(temp_data +i);}delete[]temp_data;return;
}template<class T>
void CMat<T>::swapRows(int a, int b)
{//判断if(a<0||a>=row||b<0||b>= row){//参数不符合条件return;}//new一个暂存的数据 存下b行的数据 有col项T*temp_data = new T[col];for(int j=0; j<col; j++){//将b行数据给到temp_data,b行数据用a行数据赋值,a行数据用temp_data赋值*(temp_data + j) = *(data + b*col + j);*(data + b*col + j) = *(data + a*col + j);*(data + a*col + j) = *(temp_data + j);}delete[]temp_data;return;
}template<class T>
CMat<T> CMat<T>::fetchCol(int col)
{//给定行,则矩阵为n行 1列  参数col从0开始取int mat_row = this->row;int mat_col = 1;T*data = new T[mat_row*mat_col];for (int i= 0; i< mat_row; i++){*(data + i) = *(this->data + row*i + col);}CMat<T>result_mat(mat_row, mat_col, data);return result_mat;
}template<class T>
CMat<T> CMat<T>::fetchRow(int row)
{//给定行,则矩阵为1行 n列  参数row从0开始取int mat_row =1;int mat_col= this->col;T*data = new T[mat_row*mat_col];for (int j = 0; j < mat_col; j++){*(data + j) = *(this->data + row*col + j);}CMat<T>result_mat(mat_row, mat_col,data);return result_mat;
}template<class T>
bool CMat<T>::operator!=(CMat&)
{//判断是不是同一个对象if (this == &mat){return false;}//判断数据是否相等T *target_data = mat.data;bool is_data_equal = true;for (int i = 0; i < row; i++){for (int j = 0; j < col; j++){T target_value = *(target_data + i*row + j);T cur_value = *(this->data + i*row + j);if (target_value != cur_value){is_data_equal = false;}}}if (mat.row==this->row&&mat.col==this->col&&is_data_equal){return false;}return true;
}template<class T>
bool CMat<T>::operator==(CMat&mat)
{//判断是不是同一个对象if (this == &mat){return true;}//判断数据是否相等T *target_data = mat.data;bool is_data_equal=true;for (int i = 0; i < row; i++){for (int j = 0; j < col; j++){T target_value = *(target_data + i*row + j);T cur_value = *(this->data + i*row + j);if (target_value != cur_value){is_data_equal = false;}}}if (mat.row != this->row || mat.col != this->col || !is_data_equal){return false;}return true;
}template<class T>
CMat<T>& CMat<T>::operator=(CMat&mat)
{//判断是不是同一个对象if (this== &mat){        return *this;}if (this->data != NULL){delete [] this->data;}this->row = mat.row;this->col = mat.col;this->data = new T(row*col);//深拷贝memcpy(this->data, mat.data,row*col * sizeof(T)); //后面sizeof(T)不要忘记return *this;
}template<class U>
CMat<U> operator*(CMat<U>&mat1, CMat<U>&mat2)
{U*temp_data = new U[1];*temp_data = 1;CMat<U>result_mat(1, 1, temp_data);//第一个矩阵的列数col和第二个矩阵的行数row相同才可相乘//判断是不是同一个对象if (mat1 == mat2){return  result_mat;}if (mat1.col != mat2.row || mat1.row < 0 || mat1.col < 0 || mat2.row < 0 || mat2.col < 0){//不符合要求return result_mat;}//通过判断 开始矩阵相乘int result_row = mat1.row;int result_col = mat2.col;//清除之前的内存空间,重新分配空间 !!这里不需要清除空间 析构会调用 会删除一次报错//delete[]temp_data;//temp_data = NULL;U *new_data = new U[result_row*result_col];//a第i行和b第j列相乘,相加int num = mat1.col;//取一个基准数值 应等于a列 或者b行for (int i = 0; i < result_row; i++){for (int j = 0; j < result_col; j++){//从mat1的第i行取num列数的值  从mat2的第j列取num行数的值 相乘再相加  U result_value = 0;for (int k = 0; k < num; k++){U value = (*(mat1.data + i*mat1.col + k))*(*(mat2.data + j + k*mat2.col));result_value += value;}*(new_data + i*result_col + j) = result_value;}}CMat<U>new_mat(result_row, result_col, new_data);return new_mat;
}template<class T>
CMat<T>::CMat(CMat&mat)
{if (mat.row<MinSize || mat.row>MaxSize || mat.col<MinSize || mat.col>MaxSize|| mat.data==NULL){//不符合要求assert(0);return;}this->row = mat.row;this->col = mat.col;//申请空间data = new T[row*col];//深拷贝memcpy(this->data, mat.data, row*col*sizeof(T));
}template<class T>
CMat<T>::CMat(int r, int c, T value)
{if (r<MinSize || r>MaxSize || c<MinSize || c>MaxSize){//行列不符合要求assert(0);return;}//构造data = new T[r*c];//赋值for (int cur_r = 0; cur_r < r; r++){for (int cur_c = 0; cur_c < c; c++){*(data + cur_r*cur_c - 1) = value;}}
}template<class T>
CMat<T>::CMat(int r, int c, T* arr)
{if (r<MinSize || r>MaxSize || c<MinSize || c>MaxSize || arr == NULL){assert(0);return;}//这里要再加个判断 判断 arr是否符合r*c的sizethis->row = r;this->col = c;this->data = arr;}template<class T>
CMat<T>::CMat(int r, int c)
{if (r<MinSize || r>MaxSize || c<MinSize || c>MaxSize){//行列不符合要求或者数据指向为空cout << "Struct failed---OutOfRange" << endl;return;}//开始this->data = new T[r*c];this->row = r;this->col = c;int size = r*c;cout << "需要输入:" << to_string(size) << "个数字" << "\n";for (int i = 0; i < size; i++){cout << "编号:" << to_string(i) << " " << "数值:";T input;cin >>input;//赋值*(data + i) = input;}
}template <class T>
CMat<T>::~CMat()
{if (this->data != NULL){delete[]data;}
}

(C++)矩阵模板类相关推荐

  1. Eigen(1):Matrix模板类

    Matrix是一个模板类,利用模板类可以定义矩阵类. 矩阵类模板: 1Matrix类有6个模板参数,只需要了解前3个就好了. Matrix<typename Scalar, int RowsAt ...

  2. Eigen入门之密集矩阵 1 -- 类Matrix介绍

    简介 本篇介绍Eigen中的Matrix类.在Eigen中,矩阵和向量的类型都用Matrix来表示.向量是一种特殊的矩阵,其只有一行或者一列. Matrix构造 在Matrix.h中,定义了Matri ...

  3. 2-算法 矩阵 数组类

    算法 矩阵 数组类 这类都可以看成 找横纵坐标的规律 以及操作的题 基本的模板如下 a[][] for(int i =0 ,i< n,i++) {//左下三角形for(int j =0;j< ...

  4. C++ 模板类的嵌套

    模板类的嵌套 使用函数模板,当参数是自定义数据类型(如结构体,类)时,需要通过第三代具体化自定义数据类型来解决问题. 那么对于类模板中的成员对象的数据类型也是自定义数据类型呢. 实际上,只要类中包括了 ...

  5. TermCriteria模板类

    学习写vo过程中遇到的 类功能:模板类,作为迭代算法的终止条件. 构造函数: TermCriteria(int type,int maxCount,double epsilon); 参数说明: typ ...

  6. Google Test(GTest)使用方法和源码解析——模板类测试技术分析和应用

    写C++难免会遇到模板问题,如果要针对一个模板类进行测试,似乎之前博文中介绍的方式只能傻乎乎的一个一个特化类型后再进行测试.其实GTest提供了两种测试模板类的方法,本文我们将介绍方法的使用,并分析其 ...

  7. OpenCV中的TermCriteria模板类

    2019独角兽企业重金招聘Python工程师标准>>> TermCriteria模板类,取代了之前的CvTermCriteria,这个类是作为迭代算法的终止条件的,这个类在参考手册里 ...

  8. C++编程进阶7(何时使用成员函数模板,模板类的实参推断与类型转换、继承与数组)

    二十六.何时使用成员函数模板 关于成员函数模板见https://blog.csdn.net/Master_Cui/article/details/111824152 成员函数模板主要用来兼容不同类型的 ...

  9. C++知识点61——typename与class、模板编程与继承、模板类和友元、类模板与static成员

    一.typename与class的异同 1.啥时候既可以使用typename,又可以使用class? 当表示模板参数的时候,二者没有区别 2.啥时候只能使用typename,不能使用class? 当模 ...

最新文章

  1. java字符串分割性能_String字符串性能优化的几种方案
  2. Linux的视频编程(V4L2编程)【转】
  3. 鸿蒙是学生开发的系统,9岁小学生展示鸿蒙OS开发
  4. C#数组和集合专题4(Hashtable类)
  5. 初学ASP.NET 必看
  6. 模拟服务器和客户端交互的python脚本
  7. PHP的钩子实现解析
  8. 信息学奥赛一本通(1230:寻找平面上的极大点)
  9. 拳王虚拟项目公社:有没免费虚拟资源池,虚拟资源平台该选择什么,虚拟资源整合赚钱
  10. 项目管理手记 八 SaaS模式的DRP系统是否适用
  11. 硬件设计4---什么是电感磁珠?
  12. 门店数字化转型| 美容院管理系统
  13. 【海思篇】【Hi3516DV300】六、音频输入篇
  14. table 表格合并
  15. java短信发送代码_java 短信发送 的 代码
  16. python调用chrome插件_使用Python开发chrome插件
  17. C# this.Invoke()的作用与用法、不阻塞UI界面线程的延时函数
  18. html内边距居中,HTML中详述外边距样式属性(margin)与内边距样式属性(padding)...
  19. 数学专业的考计算机博士,在数字中发现乐趣 过来人谈数学专业考研
  20. 11【门面设计模式】

热门文章

  1. [问题2014S13] 复旦高等代数II(13级)每周一题(第十三教学周)
  2. 浅谈电力通信与泛在电力物联网技术的应用与发展-Susie 周
  3. 莫烦大大TensorFlow学习笔记(8)----优化器
  4. Day2:03Windows常用快捷键
  5. SolidWorks手工绘制齿轮
  6. 快速幂运算——人见人爱A^B
  7. (笔记)AES加密在线计算工具
  8. unity3d 牧师与恶魔动作分离
  9. STIL:一个cycle中可以表示多个数据
  10. LWN:RCU近期的改动!