面向对象程序设计课程设计报告.docx
《面向对象程序设计课程设计报告.docx》由会员分享,可在线阅读,更多相关《面向对象程序设计课程设计报告.docx(22页珍藏版)》请在冰点文库上搜索。
面向对象程序设计课程设计报告
面向对象程序设计课程设计报告
第一章需求分析
1.1引言
当我们在学线性代数的时候,都需要学习矩阵的相关内容,在学习的时候,当然离不开矩阵的相关计算,例如求矩阵的加、减、乘、运算,判断两个矩阵是否相等,求矩阵的行列式以及矩阵的逆等等。
要知道其结果,往往要花比较多的时间去计算,因此,设计一个能完成这些计算的程序是很有必要的。
它可以帮助我们便捷、快速地完成计算,节约我们宝贵的时间。
1.2任务概述
(A)使用C++设计矩阵类及相应的测试主程序。
该矩阵类可进行基本的统计计算,矩阵类的每一行为一向量,基本统计计算针对该向量进行。
矩阵生成可如1方式实现,也可以从磁盘文件中读入。
矩阵的行、列数有默认值,也可通过类成员函数设置更改;如从磁盘文件读入,该磁盘文件名及其存储路径有默认值,也可通过类成员函数设置更改;矩阵类有加、减、乘、判断相等的运算成员函数;基本统计计算包括求均值、协方差;基本统计计算结果在该类对象退出作用域时可自动存入磁盘文件,该磁盘文件名及其存储路径有默认值,也可通过类成员函数设置更改。
(B)在按上述要求实现的C++类中添加可求协方差矩阵对应的行列式值和求矩阵(方阵)逆的类成员,更改测试主程序对此加以验证
要求:
(1)提交类声明头文件、类实现文件和测试程序文件3个源代码文件;
(2)2014年6月27日前完成并提交。
1.3数据描述
该程序包含一下信息:
1)、声明一个矩阵类
2)、有矩阵的输入、输出功能
3)、有完成矩阵计算个功能函数
1.4功能需求
根据要求设计一个矩阵类及相应的测试主程序,该矩阵类可进行基本的统计计算,矩阵类有加、减、乘、判断相等的运算成员函数,可求协方差矩阵对应的行列式值和求矩阵(方阵)逆的类成员。
1.5运行需求
应用VisualC++,VisualC++6.0不仅仅是一个C++编译器,而且是一个基于Windows操作系统的是集成开发环境,这种环境开发出来的软件稳定性好、可移植性强,可以编制各种的Windows应用程序。
第二章概要设计
2.1矩阵类(Matrix)设计
根据题目要求,设计矩阵类及相应的测试主程序:
矩阵类可进行基本的统计计算
详细程序代码如下:
classMatrix
{
public:
Matrix();//无参构造函数
friendvoidIn(Matrix&);//设置为友元的输入函数
friendvoidOut(Matrix&);//设置为友元的输出函数
Matrixoperator+(Matrix&);//加法重载函数
Matrixoperator-(Matrix&);//减法重载函数
Matrixoperator*(Matrix&);//乘法重载函数
friendMatrixAdjunct(Matrix&,int,int);//设置成友元的求代数余子式
frienddoubleDet(Matrix&);//设置成友元的递归求行列式
friendMatrixInv(Matrix&);//设置成友元的求矩阵的逆
private:
intm,n;//矩阵的行数和列数
Datatype*p;//矩阵的基址
};
2.2输入、输出显示矩阵模块设计
主要功能是检验从键盘输入矩阵的保存及输出显示该矩阵。
再对系统进行加、减、乘等一系列操作。
程序代码如下:
voidIn(Matrix&a)//输入函数
{
cout<<"请输入行、列数";
cin>>a.m>>a.n;inti,j;
a.p=newDatatype[a.m*a.n];
Datatype*q;
cout<<"请按行优先输入矩阵"<for(j=0;jfor(q=a.p+j*a.n,i=0;icin>>*q;
}
voidOut(Matrix&b)//输出函数
{
inti,j;
Datatype*p=b.p;
double*q;
for(i=0;ifor(q=p+i*b.n,j=0;jcout<<*q<<'\t';
if(j==b.n-1)
cout<}
}
测试输入、输出显示情况
2.3两个矩阵加、减、乘运算模块设计
程序代码如下:
MatrixMatrix:
:
operator+(Matrix&b)//加法重载函数
{
if(m!
=b.m||n!
=b.n)
{cout<<"\n行或列不匹配";
exit(0);
}
Matrixc;
c.m=m;
c.n=n;
c.p=newdouble[m*n];
inti,j;
for(i=0;ifor(j=0;jc.p[i*c.n+j]=p[i*c.n+j]+b.p[i*c.n+j];
Out(c);
returnc;
}
MatrixMatrix:
:
operator-(Matrix&b)//减法重载函数
{
if(m!
=b.m||n!
=b.n)
{cout<<"\n行或列不匹配";
exit(0);
}
Matrixc;
c.m=m;
c.n=n;
c.p=newdouble[m*n];
for(inti=0;ifor(intj=0;jc.p[i*c.n+j]=p[i*c.n+j]-b.p[i*c.n+j];
Out(c);
returnc;
}
MatrixMatrix:
:
operator*(Matrix&b)//乘法重载函数
{
Matrixc;
c.m=m;
c.n=n;
c.p=newdouble[m*n];
if(m!
=b.n)
{
cout<<"\n行列不匹配";
exit(0);
}
inti,j,k;
for(i=0;ifor(j=0;jfor(c.p[i*b.n+j]=0,k=0;kc.p[i*b.n+j]+=p[i*b.n+k]*b.p[k*b.n+j];
Out(c);
returnc;
}
测试任意两个矩阵加、减、乘情况
例如,输入以下两个矩阵,
矩阵a:
矩阵b:
123147
456258
789369
其效果如下:
2.4求矩阵对应的行列式值和求矩阵(方阵)逆设计模块
程序代码如下:
MatrixAdjunct(Matrix&a,intindexm,intindexn)//求第indexm行indexn列元素的代数余子式
{
Matrixadj;
adj.m=a.m-1;
adj.n=a.n-1;
adj.p=newdouble[(a.n-1)*(a.n-1)];
for(inti=0;i{
for(intj=0;j{
adj.p[i*(a.n-1)+j]=a.p[i*a.n+j];
}
for(intk=indexn+1;k{
adj.p[i*(a.n-1)+k-1]=a.p[i*a.n+k];
}
}
for(intm=indexm+1;m{
for(intj=0;j{
adj.p[(m-1)*(a.n-1)+j]=a.p[m*a.n+j];
}
for(intk=indexn+1;k{
adj.p[(m-1)*(a.n-1)+k-1]=a.p[m*a.n+k];
}
}
returnadj;
}
doubleDet(Matrix&a)//递归求行列式
{
doubledet=0;
if(a.m!
=a.n)
{
cout<<"不是方阵,没有行列式!
"<cout<<"求行列式退出"<}
if(a.n==1)
{
det=a.p[0];
returndet;
}
else
{
for(inti=0;i{
if(i%2==0)
det+=a.p[i*a.n]*Det(Adjunct(a,i,0));
else
det-=a.p[i*a.n]*Det(Adjunct(a,i,0));
}
}
returndet;
}
MatrixInv(Matrix&a)//求矩阵的逆
{
Matrixtemp;
temp.m=a.n;
temp.n=a.m;
temp.p=newdouble[a.m*a.n];
doubledet=Det(a);//矩阵的逆=伴随矩阵/行列式
if(det==0)//如果行列式的值为0,则没有逆
{
cout<<"此矩阵没有逆!
"<cout<<"求矩阵逆退出!
";
exit(0);
}
for(inti=0;i{
for(intj=0;j{
if((i+j)%2==0)
temp.p[i*temp.m+j]=Det(Adjunct(a,i,j))/det;
else
temp.p[i*temp.m+j]=-Det(Adjunct(a,i,j))/det;
}
}
returntemp;
}
求矩阵对应的行列式值和求矩阵(方阵)逆设计模块测试情况
注意:
本程序输出的逆矩阵是先输出列的,如上图所示。
按照正常的显示是先输出行的。
上图中的a矩阵的逆矩阵应看成:
-21
1.5-0.5
附录:
程序代码
//Matrix.h文件,Matrix类的定义
#include
usingnamespacestd;
typedefdoubleDatatype;
classMatrix{
public:
Matrix();//无参构造函数
friendvoidIn(Matrix&);//设置为友元的输入函数
friendvoidOut(Matrix&);//设置为友元的输出函数
Matrixoperator+(Matrix&);//加法重载函数
Matrixoperator-(Matrix&);//减法重载函数
Matrixoperator*(Matrix&);//乘法重载函数
friendMatrixchange(Matrix&);//转置函数
friendMatrixAdjunct(Matrix&,int,int);//设置成友元的求代数余子式
frienddoubleDet(Matrix&);//设置成友元的递归求行列式
friendMatrixInv(Matrix&);//设置成友元的求矩阵的逆
private:
intm,n;//矩阵的行数和列数
Datatype*p;//矩阵的基址
};
//Matrix.cpp文件,Matrix类的实现
#include"Matrix.h"
#include
usingnamespacestd;
Matrix:
:
Matrix(){
m=0;
n=0;
}
voidIn(Matrix&a){//输入函数
cout<<"请输入行、列数";
cin>>a.m>>a.n;inti,j;
a.p=newDatatype[a.m*a.n];
Datatype*q;
cout<<"请按行优先输入矩阵"<for(j=0;jfor(q=a.p+j*a.n,i=0;icin>>*q;
}
voidOut(Matrix&b){//输出函数
inti,j;
Datatype*p=b.p;
double*q;
for(i=0;ifor(q=p+i*b.n,j=0;jcout<<*q<<'\t';
if(j==b.n-1)
cout<}
}
MatrixMatrix:
:
operator+(Matrix&b){//加法重载函数
if(m!
=b.m||n!
=b.n)
{cout<<"\n行或列不匹配";
exit(0);
}
Matrixc;
c.m=m;
c.n=n;
c.p=newdouble[m*n];
inti,j;
for(i=0;ifor(j=0;jc.p[i*c.n+j]=p[i*c.n+j]+b.p[i*c.n+j];
Out(c);
returnc;
}
MatrixMatrix:
:
operator-(Matrix&b){//减法重载函数
if(m!
=b.m||n!
=b.n)
{cout<<"\n行或列不匹配";
exit(0);
}
Matrixc;
c.m=m;
c.n=n;
c.p=newdouble[m*n];
for(inti=0;ifor(intj=0;jc.p[i*c.n+j]=p[i*c.n+j]-b.p[i*c.n+j];
Out(c);
returnc;
}
MatrixMatrix:
:
operator*(Matrix&b){//乘法重载函数
Matrixc;
c.m=m;
c.n=n;
c.p=newdouble[m*n];
if(m!
=b.n)
{
cout<<"\n行列不匹配";
exit(0);
}
inti,j,k;
for(i=0;ifor(j=0;jfor(c.p[i*b.n+j]=0,k=0;kc.p[i*b.n+j]+=p[i*b.n+k]*b.p[k*b.n+j];
Out(c);
returnc;
}
MatrixAdjunct(Matrix&a,intindexm,intindexn)//求第indexm行indexn列元素的代数余子式
{
Matrixadj;
adj.m=a.m-1;
adj.n=a.n-1;
adj.p=newdouble[(a.n-1)*(a.n-1)];
for(inti=0;i{
for(intj=0;j{
adj.p[i*(a.n-1)+j]=a.p[i*a.n+j];
}
for(intk=indexn+1;k{
adj.p[i*(a.n-1)+k-1]=a.p[i*a.n+k];
}
}
for(intm=indexm+1;m{
for(intj=0;j{
adj.p[(m-1)*(a.n-1)+j]=a.p[m*a.n+j];
}
for(intk=indexn+1;k{
adj.p[(m-1)*(a.n-1)+k-1]=a.p[m*a.n+k];
}
}
returnadj;
}
doubleDet(Matrix&a)//递归求行列式
{
doubledet=0;
if(a.m!
=a.n)
{
cout<<"不是方阵,没有行列式!
"<cout<<"求行列式退出"<}
if(a.n==1)
{
det=a.p[0];
returndet;
}
else
{
for(inti=0;i{
if(i%2==0)
det+=a.p[i*a.n]*Det(Adjunct(a,i,0));
else
det-=a.p[i*a.n]*Det(Adjunct(a,i,0));
}
}
returndet;
}
MatrixInv(Matrix&a)//求矩阵的逆
{
Matrixtemp;
temp.m=a.n;
temp.n=a.m;
temp.p=newdouble[a.m*a.n];
doubledet=Det(a);//矩阵的逆=伴随矩阵/行列式
if(det==0)//如果行列式的值为0,则没有逆
{
cout<<"此矩阵没有逆!
"<cout<<"求矩阵逆退出!
";
exit(0);
}
for(inti=0;i{
for(intj=0;j{
if((i+j)%2==0)
temp.p[i*temp.m+j]=Det(Adjunct(a,i,j))/det;
else
temp.p[i*temp.m+j]=-Det(Adjunct(a,i,j))/det;
}
}
returntemp;
}
//main.cpp主函数测试部分
#include"Matrix.h"
#include
usingnamespacestd;
voidmain()
{
Matrixa,b,c;
cout<<"对于a矩阵";
In(a);
cout<<"a="<Out(a);
cout<<"对于b矩阵";
In(b);
cout<<"b="<Out(b);
cout<<"a+b="<c=a+b;
cout<cout<<"a-b="<c=a-b;
cout<cout<<"a*b="<c=a*b;
cout<cout<<"a的行列式为:
"<cout<cout<<"b的行列式为:
"<cout<cout<<"a矩阵的逆矩阵为:
"<c=Inv(a);
Out(c);
cout<cout<<"注意,这里是先输出逆矩阵的列的:
"<cout<<"b矩阵的逆矩阵为:
"<c=Inv(b);
Out(c);
cout<}
参考文献
《C++面向对象程序设计》清华大学出版社
注:
判断相等的运算,基本统计计算求均值、协方差,没有做
面向对象程序设计(课程设计)成绩评定表
评分项目
分值
得分
程序(系统)
(60分)
原创性
15
程序功能
20
代码质量(健壮性和可扩展性)
15
核心代码和功能模块注释
10
设计报告(40分)
课题来源&任务描述
10
系统设计
15
代码编写与实现结果说明
15
成绩总计
老师签字:
蒋正锋