C++课程设计矩阵乘法计算.docx
《C++课程设计矩阵乘法计算.docx》由会员分享,可在线阅读,更多相关《C++课程设计矩阵乘法计算.docx(19页珍藏版)》请在冰豆网上搜索。
C++课程设计矩阵乘法计算
C++课程设计报告
姓名学号班级0804任课教师时间2009.9
教师指定题目矩阵乘法计算评定难易级别A级
实验报告成绩
自评成绩:
优
一、题目名称:
矩阵乘法计算
二、难易等级:
A级
三、程序设计思想
1、建立矩阵类的类模板,通过实例化形成模板类,再实例化成矩阵对象,大大缩短了代码的长度,同时也方便了对象的建立;
classCMatrix//矩阵类的模板
{
T**Mat;//矩阵的头指针
intnRow;//矩阵的行数
intnCol;//矩阵的列数
public:
CMatrix();//缺省构造函数
CMatrix(T**mat,introw,intcol);//构造函数
CMatrix(introw,intcol);//构造函数
CMatrix(introw,intcol,intk);//构造函数,从键盘输入矩阵
VoidShow();//输出
VoidInputFromFile();//从文件中输入矩阵
friendCMatrixoperator*(CMatrix&mat1,CMatrix&mat2);//重载乘法
};
2、依照模板,在模板外依次定义相关的函数模板,再通过实例化建立相应的成员函数,同样方便快捷,避免了代码的冗长,程序层次清晰;
template
CMatrix:
:
CMatrix(introw,intcol)//两个参数的构造函数
{
……
}
3、建立选择函数choose,实现程序的多态性,同时也简化了主函数的内容,主函数只需简单调用choose函数就能执行整个程序的相关功能;
voidchoose()//数据类型选择函数
{
cout<<"时间:
2009年9月26日\n"<"<"<电子技术"<cout<整型"<浮点型"<双精度型"<cout<<"请选择数据类型:
\n";
intsjlx;
cin>>sjlx;
switch(sjlx)
{
case1:
{
choose1
(1);
}break;
case2:
{
choose1(0.0);
}break;
case3:
{
choose1(1e-10);
}break;
default:
cout<<"输入选择错误!
!
!
"<}
4、main函数中加入相关界面输出语句和程序结束语句,使程序更加人性化,并加入了异常处理语句,使程序运行的更加稳定可靠;
四、程序增加功能及实现办法
1、模板的使用
本程序使用了大量的模板,譬如矩阵类模板、相关函数模板,以T为模板参数,通过对T的不同类型的选择实现相应的运算处理。
其中choose1()函数本是无参函数,为了方便模板化,给其赋以伪参数T,在执行时通过T的取值生成相应的函数模板,真可谓方便!
!
template
voidchoose1(T)//数据输入类型选择函数模板,其中T为伪参数,用于函数模板实例化
{
…………
}
调用时:
switch(sjlx)
{
case1:
{
choose1
(1);//生成int型模板
}break;
case2:
{
choose1(0.0);//生成float型模板
}break;
case3:
{
choose1(1e-10);//生成double型模板
}break;
default:
cout<<"输入选择错误!
!
!
"<}
2、矩阵类的构造
本程序采用二级指针动态开辟内存空间,结构合理,操作方便,节省内存使用;
其中数据结构如下:
Mat-->Mat[0]----->Mat[0][0]Mat[0][1]……Mat[0][j]
Mat[1]----->Mat[1][0]Mat[1][1]……Mat[1][j]
:
:
Mat[i]----->Mat[i][0]Mat[i][1]……Mat[i][j]
实现构造的代码为:
template
CMatrix:
:
CMatrix(introw,intcol)//两个参数的构造函数
{
inti,j;
nRow=row,nCol=col;
Mat=newT*[nRow];
for(i=0;i{
Mat[i]=newT[nCol];
}
cout<<"请输入数据:
\n";
for(i=0;ifor(j=0;j{
cout<<"第["<
";
cin>>Mat[i][j];
}
}
3、运算符的重载
要实现矩阵间的乘法运算,有必要对其运算符进行重载。
而乘法运算符又要针对不同数据类型进行运算,因此,对运算符重载函数模板化也是很有必要的。
template
CMatrixoperator*(CMatrix&mat1,CMatrix&mat2)//矩阵乘法运算符重载
{
CMatrixmat3(mat1.nRow,mat2.nCol,0);
for(inti=0;ifor(intj=0;j{
mat3.Mat[i][j]=0;
for(intk=0;kmat3.Mat[i][j]+=mat1.Mat[i][k]*mat2.Mat[k][j];
}
returnmat3;
}
无论何种数据类型的矩阵,其乘法算法都是一致的,详见以上代码。
4、数据的输入输出
本程序数据可以初始赋值也可以通过键盘输入,还可以从外部文件输入。
键盘输入:
cout<<"请输入数据:
\n";
for(i=0;ifor(j=0;j{
cout<<"第["<
";
cin>>Mat[i][j];
}
文件输入:
template
voidCMatrix:
:
InputFromFile()//矩阵文件输入函数
{
ifstreaminfile;
infile.open("daijp.txt",ios:
:
nocreate);
if(!
infile)
{
cout<<"输入文件不存在,请先建立输入文件\n";
exit(0);
}
for(inti=0;ifor(intj=0;j{
infile>>Mat[i][j];
}
infile.close();
}
矩阵的输出:
template
voidCMatrix:
:
Show()//矩阵输出函数
{
inti,j;
for(i=0;i{
cout<for(j=0;jcout<}
cout<}
5、程序的菜单设计和异常处理
本程序主要是使用switch开关语句进行菜单设计,通过读取键入不同的值进入不同的子句执行入口,进而实现不同的功能。
通过比较输入的两矩阵的行和列判断能否进行乘法运算,防止乱输入出现的异常。
同时,本程序只是在主函数中使用了少量goto语句,并非滥用,非但没有使程序流程无规律,反倒使程序代码更加简洁,层次结构更加清晰。
voidmain()//主函数
{
loop:
cout<<"***************************************************************\n";
cout<<"******************************************\n";
cout<<"***************";
cout<<"\n\n\n************************您好,欢迎使用矩阵乘法计算程序!
*************************\n";
cout<<"***************\n";
cout<<"******************************************\n";
cout<<"***************************************************************\n\n";
choose();
loop1:
cout<<"想继续执行吗?
"<inta;
cin>>a;
switch(a)
{
case1:
gotoloop;
break;
case2:
{
cout<<"非常感谢您的使用!
!
!
"<"<"<151"<12345678"<cout<<"按任意键退出……"<cin.get();
cin.get();//去除缓冲区的回车符
exit
(1);
}
default:
cout<<"输入选择错误!
!
!
"<gotoloop1;
}
}
五、程序设计中遇到的主要问题及解决办法
1、无法实现文件输入
主要原因是输入之前调用的是默认构造函数,只是简单赋值,并未开辟内存空间,后来调用带参构造函数就可以正常输入数据;
2、重载乘法运算的函数无法重载
经检查发现,由于重载的是友元函数,函数不存在this指针,因此必须显式地调用两个相乘的矩阵类。
六、设计中尚存的不足
1、功能还不够强大,只能做简单的矩阵乘法,我所期望的是能够做各种混合运算,具有强大处理功能的实用程序,无奈所学知识有限,时间仓促;
2、矩阵的输出还有一个问题,当矩阵的行数超过了窗口一行所能显示的数时,这时又该怎么来输出矩阵呢?
3、关于异常处理这,我觉得处理功能也不是很行,觉得还是应该建立全面的异常检测与异常处理机制;
七、设计的感想和心得体会
1、本程序解皆系本人自主开发,开发过程自然十分艰辛,使我深深地懂得了软件版权保护的重要性;
2、此次程序设计使我透彻地领悟到面向对象的程序设计的优点和强大生命力,特别是类和模板的使用,使程序的兼容性和扩展能力都大大加强,比如我们想要再做一个处理其他类型数据的矩阵的乘法计算,只需要添加一个相应的类型声明就可以利用模板迅速构造出来;
3、对凡事都应当有毅力,不要中途放弃。
在开发过程中,好几次遇到困难我都想再换一个别的程序或找同学拷一个程序,但我最终还是坚持下来了。
永不言弃,你就一定会成功的;
4、磨刀不误砍柴工。
在刚拿到任务时,书上的关键代码我也是看的一头雾水,后来我将上学期的课本认真研读一遍之后,感觉收获真的不少,接着编起程来就顺手好多了;
5、通过这次程序设计,我相信我十月份的等级考试已经没多大问题了,哈哈……
修改后的程序(矩阵乘法计算)
#include
#include
#include
#include
template
classCMatrix//矩阵类的模板
{
T**Mat;//矩阵的头指针
intnRow;//矩阵的行数
intnCol;//矩阵的列数
public:
CMatrix();//缺省构造函数
CMatrix(introw,intcol);//构造函数
CMatrix(introw,intcol,intk);//构造函数,从键盘输入矩阵
voidShow();//输出
voidInputFromFile();//从文件中输入矩阵
friendCMatrixoperator*(CMatrix&mat1,CMatrix&mat2);//重载乘法
};
template
CMatrix:
:
CMatrix()//缺省构造函数
{
nRow=100,nCol=100;
Mat=newT*[100];
for(inti=0;i<100;i++)
{
Mat[i]=newT[100];
}
}
template
CMatrix:
:
CMatrix(introw,intcol)//两个参数的构造函数
{
inti,j;
nRow=row,nCol=col;
Mat=newT*[nRow];
for(i=0;i{
Mat[i]=newT[nCol];
}
cout<<"请输入数据:
\n";
for(i=0;ifor(j=0;j{
cout<<"第["<
";
cin>>Mat[i][j];
}
}
template
CMatrix:
:
CMatrix(introw,intcol,intk)//三个参数的构造函数
{
nRow=row,nCol=col;
Mat=newT*[nRow];
for(inti=0;i{
Mat[i]=newT[nCol];
}
}
template
voidCMatrix:
:
Show()//矩阵输出函数
{
inti,j;
for(i=0;i{
cout<for(j=0;jcout<}
cout<}
template
voidCMatrix:
:
InputFromFile()//矩阵文件输入函数
{
ifstreaminfile;
infile.open("daijp.txt",ios:
:
nocreate);
if(!
infile)
{
cout<<"输入文件不存在,请先建立输入文件\n";
exit(0);
}
for(inti=0;ifor(intj=0;j{
infile>>Mat[i][j];
}
infile.close();
}
template
CMatrixoperator*(CMatrix&mat1,CMatrix&mat2)//矩阵乘法运算符重载
{
CMatrixmat3(mat1.nRow,mat2.nCol,0);
for(inti=0;ifor(intj=0;j{
mat3.Mat[i][j]=0;
for(intk=0;kmat3.Mat[i][j]+=mat1.Mat[i][k]*mat2.Mat[k][j];
}
returnmat3;
}
template
voidchoose1(T)//数据输入类型选择函数模板,其中T为伪参数,用于函数模板实例化
{
cout<<"<1>初始化赋值"<键盘输入"<文件输入"<intsrfs;
cout<<"请选择数据输入方式:
\n";
cin>>srfs;
switch(srfs)//用于选择不同的输入方式
{
case1:
{
CMatrixmata,matb,matc;
}break;
case2:
{
inta,b,c,d;
cout<<"请输入第一个矩阵的行数和列数:
"<cin>>a>>b;
CMatrixmata(a,b);
cout<<"请输入第二个矩阵的行数和列数:
"<cin>>c>>d;
if(b!
=c)
{
cout<<"错误!
!
!
两矩阵不能相乘!
!
!
\n";
break;
}
CMatrixmatb(c,d);
CMatrixmatc(a,d,0);
mata.Show();
matb.Show();
matc=mata*matb;
cout<<"两矩阵相乘结果为:
\n";
matc.Show();
}break;
case3:
{
inta,b,c,d;
cout<<"请输入第一个矩阵的行数和列数:
"<cin>>a>>b;
CMatrixmata(a,b,0);
cout<<"请输入第二个矩阵的行数和列数:
"<cin>>c>>d;
if(b!
=c)
{
cout<<"错误!
!
!
两矩阵不能相乘!
!
!
\n";
break;
}
CMatrixmatb(c,d,0);
CMatrixmatc(a,d,0);
mata.InputFromFile();
matb.InputFromFile();
mata.Show();
matb.Show();
matc=mata*matb;
cout<<"两矩阵相乘结果为:
\n";
matc.Show();
}break;
default:
cout<<"输入选择错误!
!
!
"<}
}
voidchoose()//数据类型选择函数
{
cout<<"时间:
2009年9月26日\n"<"<"<"<cout<整型"<浮点型"<双精度型"<cout<<"请选择数据类型:
\n";
intsjlx;
cin>>sjlx;
switch(sjlx)
{
case1:
{
choose1
(1);
}break;
case2:
{
choose1(0.0);
}break;
case3:
{
choose1(1e-10);
}break;
default:
cout<<"输入选择错误!
!
!
"<}
cout<}
voidmain()//主函数
{
loop:
cout<<"***************************************************************\n";
cout<<"******************************************\n";
cout<<"***************";
cout<<"\n\n\n************************您好,欢迎使用矩阵乘法计算程序!
*************************\n";
cout<<"***************\n";
cout<<"******************************************\n";
cout<<"***************************************************************\n\n";
choose();
loop1:
cout<<"想继续执行吗?
"<inta;
cin>>a;
switch(a)
{
case1:
gotoloop;
break;
case2:
{
cout<<"非常感谢您的使用!
!
!
"<"<"<"<"<cout<<"按任意键退出……"<cin.get();
cin.get();//去除缓冲区的回车符
exit
(1);
}
default:
cout<<"输入选择错误!
!
!
"<gotoloop1;
}
}