当前位置: 首页 > news >正文

第10章 模板与泛型编程 编程题#2:模板类编写

编程题#2:模板类编写

编写模板类Matrix,支持任意数据类型的矩阵,重载+,-,*,=,==,[]等操作。利用int,double, 类complex(包含实数real,虚数virt两部分) 等数据类型测试所写matrix类接口。

template<classT>classsquare_matrix{protected:Tp val[max_size][max_size];intsidelen;// sidelen ≤ 12public:square_matrix(intr,intc);/* … */};

Solution

分析

要求设计一个方阵类型并重载运算符。

根据基础的线性代数知识,一种比较符合大家感性认识的运算符重载设计如下:

  • ++=--=:矩阵加法、矩阵减法,无需多说。
  • **=:可以是矩阵乘法,也可以是矩阵的数乘
  • //=:矩阵除以一个数
  • ^^=:矩阵的幂次
  • ++--:有些人倾向于将“矩阵++/- -”理解为加上或减去单位矩阵,也有人倾向于理解为所有元素加上或减去 1。
  • []:重载下标运算符,直接调取对应位置的元素即可。

代码

#include<iostream>#include<iomanip>usingnamespacestd;template<typenameTp>classsquare_matrix{public:// Construct the matrix by a known side length value(no greater than 12).square_matrix(intlen):sidelen(len){memset(val,0,sizeof(val));}square_matrix(square_matrix<Tp>&another){this->sidelen=another.sidelen;memcpy(this->val,another.val,sizeof(this->val));}square_matrix<Tp>&operator=(square_matrix<Tp>another){this->sidelen=another.sidelen;memcpy(this->val,another.val,sizeof(this->val));return*this;}private:// Maximum size of the matrix.// The calculation rely on recursion so the side length of the matrix cannot be too large.// Calculation will take a very long time to finish if side length is greater than 12.staticconstintmax_size=12;// The matrix and its real side length.Tp val[max_size][max_size];intsidelen;// sidelen ≤ 12private:// Use Laplace's expansion method to calculate determinant.// This function is not allowed to call from outside.Tplaplace_expansion(intr,intc);public:// Modify matrix size.voidmodify_size(intnewlen){sidelen=newlen;}// Modify specific value.voidmodify_value(introw,intcol,Tp value){this->val[row][col]=value;}// Inputvoidinput(void){for(inti=0;i<=sidelen-1;i+=1)for(intj=0;j<=sidelen-1;j+=1)cin>>val[i][j];}// Get sizeintgetsize(void)const{returnsidelen;}// Get matrixautogetmatrix(void){returnval;}public:// Use subscript operator to get values.Tp*operator[](introw){returnval[row];}public:// Use plus operator to do plus calculation.square_matrix<Tp>&operator+=(square_matrix<Tp>&another){// Two matrixes have the same side length is expected.if(this->sidelen!=another.sidelen)throwinvalid_argument("Two matrixes should have same side length!");elsefor(inti=0;i<=sidelen-1;i+=1)for(intj=0;j<=sidelen-1;j+=1)val[i][j]+=another[i][j];return*this;}square_matrix<Tp>operator+(square_matrix<Tp>&another){// Two matrixes have the same side length is expected.if(this->sidelen!=another.sidelen)throwinvalid_argument("Two matrixes should have same side length!");else{square_matrix<Tp>result(this->sidelen);for(inti=0;i<=sidelen-1;i+=1)for(intj=0;j<=sidelen-1;j+=1)result[i][j]=val[i][j]+another[i][j];returnresult;}}// Use plus operator to do minus calculation.square_matrix<Tp>&operator-=(square_matrix<Tp>&another){// Two matrixes have the same side length is expected.if(this->sidelen!=another.sidelen)throwinvalid_argument("Two matrixes should have same side length!");elsefor(inti=0;i<=sidelen-1;i+=1)for(intj=0;j<=sidelen-1;j+=1)val[i][j]-=another[i][j];return*this;}square_matrix<Tp>operator-(square_matrix<Tp>&another){// Two matrixes have the same side length is expected.if(this->sidelen!=another.sidelen)throwinvalid_argument("Two matrixes should have same side length!");else{square_matrix<Tp>result(this->sidelen);for(inti=0;i<=sidelen-1;i+=1)for(intj=0;j<=sidelen-1;j+=1)result[i][j]=val[i][j]-another[i][j];returnresult;}}// Multiply by a factor.square_matrix<Tp>&operator*=(Tp times)noexcept{for(inti=0;i<=sidelen-1;i+=1)for(intj=0;j<=sidelen-1;j+=1)val[i][j]*=times;return*this;}square_matrix<Tp>operator*(Tp times)noexcept{square_matrix<Tp>result=*this;for(inti=0;i<=sidelen-1;i+=1)for(intj=0;j<=sidelen-1;j+=1)result[i][j]*=times;returnresult;}// Divide by a factor.square_matrix<Tp>&operator/=(Tp divisor){if(divisor==0)throwinvalid_argument("Divisor cannot be zero!");elsefor(inti=0;i<=sidelen-1;i+=1)for(intj=0;j<=sidelen-1;j+=1)val[i][j]/=divisor;return*this;}square_matrix<Tp>operator/(Tp divisor){if(divisor==0)throwinvalid_argument("Divisor cannot be zero!");else{square_matrix<Tp>result=*this;for(inti=0;i<=sidelen-1;i+=1)for(intj=0;j<=sidelen-1;j+=1)result[i][j]=val[i][j]/divisor;return*this;}}// operator ++ will be used as adding an identity matrix, which is also known as diag(1,1,...,1).square_matrix<Tp>&operator++()noexcept{for(inti=0;i<=sidelen-1;i+=1)val[i][i]+=1;return*this;}// Operator -- will be used as subtracting an identity matrix.square_matrix<Tp>&operator--()noexcept{for(inti=0;i<=sidelen-1;i+=1)val[i][i]-=1;return*this;}// Matrix multiplesquare_matrix<Tp>operator*(square_matrix<Tp>another){square_matrix<Tp>result(this->sidelen);inti,j,k;for(i=0;i<sidelen;i+=1)for(j=0;j<sidelen;j+=1)for(k=0;k<sidelen;k+=1)result[i][j]+=val[i][k]*another[k][j];returnresult;}square_matrix<Tp>operator*=(square_matrix<Tp>another){square_matrix<Tp>temp(this->sidelen);inti,j,k;for(i=0;i<sidelen;i+=1)for(j=0;j<sidelen;j+=1)for(k=0;k<sidelen;k+=1)temp[i][j]+=val[i][k]*another[k][j];*this=temp;return*this;}public:// Use Laplace's expansion method to calculate determinant.Tpdeterminant(Tp _matrix[12][12],intsize);// Calculate adjugate matrix.// Hint: Inverse matrix multiply by determinant value is adjugate matrix.square_matrix<Tp>adjugate(void);public:voidoutput(){intwidth[12]={0};for(inti=0;i<=sidelen-1;i+=1){for(intj=0;j<=sidelen-1;j+=1){if(i==0)printf("\u250c ");elseif(i==sidelen-1)printf("\u2514 ");elseprintf("\u2502 ");for(j=0;j<sidelen;j+=1)cout<<left<<setw(4)<<val[i][j];if(i==0)printf("\u2510 ");elseif(i==sidelen-1)printf("\u2518 ");elseprintf("\u2502 ");cout<<endl;}}}};intmain(){cout<<__FILE__<<endl;cout<<__TIME__<<endl;cout<<__LINE__<<endl;cout<<_MSVC_LANG<<endl;square_matrix<int>A(2);A.input();square_matrix<int>B=A;(A+A).output();(++A).output();(A*10+B).output();(--A).output();A*=4;A.output();A/=2;A.output();A*=A;A.output();}
http://www.rkmt.cn/news/1502530.html

相关文章:

  • 深度解析AlgerMusicPlayer:基于Electron+Vue3的第三方网易云音乐播放器技术方案与实战指南
  • 3分钟搞定Windows ADB环境:一键自动化驱动安装解决方案
  • ZenlessZoneZero-OneDragon:绝区零自动化辅助工具的技术架构解析与实现原理
  • 用CH32X035做个“万能钥匙”:手把手教你DIY一个PD/QC快充诱骗器(附源码)
  • GHelper深度解析:如何通过轻量级架构重新定义华硕笔记本性能管理
  • Zotero Style:重塑文献管理体验的可视化增强神器
  • GanttProject深度解析:如何用开源架构实现企业级项目管理
  • Figma中文界面本地化:为什么专业翻译比机器翻译更能提升设计效率?
  • 2026年6月,国产PCB行业迎来新一轮技术升级与市场洗牌
  • 如何用700欧元预算将随机割草机升级为RTK GPS智能机器人?
  • 如何快速搭建个人付费墙绕过工具:13ft Ladder终极指南
  • 用FPGA驱动WS2812B灯带:手把手教你从Verilog状态机到动态图像显示
  • 编写程序汇总智能跑步机运动数据,计算运动强度,卡路里消耗,评估运动达标率。
  • 南宁旧金首饰回收多少钱一克 内行避坑实操指南 - 余生黄金回收
  • 别再硬啃公式了!用Simscape Multibody从SolidWorks到MATLAB,手把手复现一阶倒立摆LQR控制
  • Mobaxterm中文版终极指南:5步掌握免费远程管理工具
  • 【Kafka源码解读和使用指南】第34篇:Kafka消费者配置全解析——提升消费性能的20个关键参数
  • 南充黄金回收行情报价 本地变现避坑完整实用攻略 - 余生黄金回收
  • 2026苏州地坪翻新公司推荐榜:聚焦专业服务与品质保障 - 品牌排行榜
  • AD7606双通道数据采集实战:基于STM32 HAL库的SPI轮询与DMA传输效率对比
  • 连云港黄金回收避坑指南2026年6月最新行情解读 - 润富黄金回收
  • MySQL 大数据量场景下的表结构与索引设计指南
  • Unity编辑器内快速打包资源为.unity3d文件的即用型工具集
  • 终极免费工具:如何用ZenTimings解锁AMD Ryzen内存性能的全部潜力
  • 电站接力器拉线位移传感器DT-C-400-U
  • 微软、谷歌、苹果等科技动态汇总:新品发布、功能更新及行业热点全知晓
  • 中文LLaMA/Alpaca全流程实践包:LoRA微调、4/8-bit量化、Gradio本地对话演示全集成
  • 2026燃油传感器压装技术解析与专业厂家盘点:压装浮动头/压装监测仪/四柱伺服压机/多级电动缸/大负载伺服电动缸/选择指南 - 优质品牌商家
  • 2026年成都无动力游乐设备厂家权威资质与服务评测:grg异形雕塑成都厂家/四川一站式雕塑设计制作厂家/实力盘点 - 优质品牌商家
  • 别再拍脑袋了!用Python模拟M/M/1排队系统,5分钟搞定客服中心容量规划