gai通信工程专业面向对象课程要求与指导_第1页
gai通信工程专业面向对象课程要求与指导_第2页
免费预览已结束,剩余17页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、课程设计任务书学院信息科学与工程专业通信工程学生姓名学号设计题目静态查 卜找类模板的1勺设计与实现内容及要求:在非数值运算问题中,数据存储量一般很大,为了在大量信息中找到某些 值,就需要用到查找技术。基于线性表的查找具体可分为顺序查找,折半查找 和分块查找。折半查找又分为递归和非递归两类。要求采用 C+语言,建立一维数组数据结构的模板类,使一维数组中的数 据元素可以是 char, int, float 等多种数据类型,并对数组元素进行静态查找。主 要完成如下功能:(1)实现数组数据的输入和输出;(2)对数组进行顺序查找;(3)对有序数组进行折半查找(递归算法);(4)对有序数组进行折半查找(非

2、递归算法);(5) 将每种查找功能作为类的成员函数实现,编写主函数测试上述查找 功能。进度安排:第 17 周:分析题目,查阅课题相关资料,进行类设计、算法设计;第 18 周:程序的设计、调试与实现;第 19 周:程序测试与分析,撰写课程设计报告,进行答辩验收。指导教师(签字):学院院长(签字)年月日年月日1 需求分析-0 - 2 算法基本原理-0 -3 类设计 - 2 -4 详细设计 - 2 -4.1 类的接口设计 -2-4.2 类的实现- 4 -4.3 主函数设计 - 85 DOS 界面程序运行结果及分析 - 9 -5.1 程序运行结果 -9-5.2 运行结果分析 -116 基于 MFC 的

3、图形界面程序开发 - 11 -6.1 基于 MFC 的图形界面程序设计 -116.2 程序测试 -146.3 MFC 程序编写总结 - 157 参考文献 - 15 -1 需求分析(1)查找运算在实际生活中使用频率高,如帐户查询、订票查询及股市查 询等,一些实时查询系统的效率也格外重要。(2)假定被查找的对象是由一组结点(元素)组成的表或文件,而每个结 点则由若干个数据项组成。所谓的查找,即给定一个待查数据值,在表的指定 数据项中查找等于待查数据值的结点。若找到,则查找成功,返回该结点的信 息或该结点在表中的位置;否则查找失败,返回相关提示信息。(3)静态查找表查找方式包括顺序查找、折半查找(递

4、归和非递归)。2 算法基本原理1 顺序查找在查找的存储方式中,顺序表是最简单的一种。建立在其上的顺序查找是从 表的一端开始,顺序扫描,依次将扫描到的元素和待查数值比较。若当前元素 的数据值与待查数据值相等,则查找成功;若扫描结束后,仍未找到数据值等 于待查数据值的元素,则查找失败。顺序查找实例如下图:*顺序表的顺序查找 *当前顺序表如下:0 1 2 3 471 68 74 17 20 请输入要查找的元素: 74 查找经过如下: 第一趟顺序查找的结果为:0 1 2 3 471 68 74 17 20T第二趟顺序查找的结果为:0 1 2 3 471 68 74 17 20T第三趟顺序查找的结果为:

5、 0 1 2 3 4 71 68 74 17 20查找结果:你要查找的元素 74 是第 3 个元素2 折半查找(1)非递归折半查找折半查找是一种效率较高的查找方法,但要求作用于有序顺序表。其基本 思想是:最初把整个有序顺序表作为查找区域,每次用待查数据值与查找区域 中间元素比较,分以下三种情况处理:如果待查数据值等于中间元素,则查找 成功;如果待查数据值小于中间元素,则继续在前半区域查找;如果待查数据 值大于中间元素,则继续在后半区域查找。查找过程中,每次与中间元素比较,就可以确定查找是否成功。如不成 功,则当前查找区域缩小一半,这样查找区域逐渐缩小。如果查找区域最终缩 小到不存在,则表示查找

6、不到这个数据。非递归折半查找实例:当前有序顺序表如下:0 1 2 3 4 5 69 18 26 27 29 32 40 请输入要查找的元素: 26 查找经过如下:第 1 趟折半查找结果为:0 1 2 3 4 5 69 18 26 27 29 32 40T第 2 趟折半查找结果为:0 1 2 3 4 5 69 18 26 27 29 32 40T第 3 趟折半查找结果为:0 1 2 3 4 5 69 18 26 27 29 32 40T查找结果:你要查找的元素 26 是第 3 个元素(2)递归折半查找3 类设计从上面的算法分析可以看到,本设计面临的计算问题的关键是矩阵运算。 可以定义一个矩阵类

7、Matrix 作为基类,然后由矩阵类派生出线性方程组类 Linequ。矩阵类*非递归折半查找*Matrix 只处理 n 沟类型的方阵,方阵用一个一维数组来存放, 矩阵类 Matrix 的数据成员包括数组的首地址和n,矩阵类 Matrix 的功能有设置矩阵的值 SetMatrix ()和显示矩阵 PrintM ()等。从问题的需要来看,线性方程组类 Linequ 的数据除了由矩阵类 Matrix 继承 过来用于存放系数矩阵 A 的成员外,还应该包括存放解向量 x 和方程右端向量 b 的数组首地址。线性方程组类 Linequ 的主要操作有设置 SetLinequ( )、显示 PrintL( )、求

8、解 Solve( )及输出方程的解 showX ( )。可以通过定义线性 方程组类 Linequ 的新增成员函数来实现这些针对方程组求解的功能。矩阵类 Matrix 和线性方程组类 Linequ 的组成及相互关系如图 1 所示。图1 Matrix类和Linequ类的派生关系的UML图形表示在线性方程组的求解过程中,在线性方程组类Linequ 的成员函数 Solve 中需要访问基类矩阵类 Matrix 的数据成员,利用公有继承方式派生,同时将 Matrix 类中的数据成员的访问控制设置为保护类型。这样,经过公有派生之 后,基类的保护成员在派生类中依然是保护成员,可以被派生类的成员函数访 问。4

9、详细设计整个程序分为三个独立的文档, Linequ.h 文件中包括矩阵类 Matrix 和线性 方程组类 Linequ 的声明, Linequ.cpp 文件中包括这两个类的成员函数实现文 件; ma in.cpp 文件包括程序的主函数,主函数中定义了一个类Linequ 的对象,通过这个对象求解一个四元线性方程组。4.1类的接口设计/Linequ.h 文件,实现类的声明#include #include using n amespace stdclass Matrix/基类 Matrix 声明public:/外部接口Matrix(int dims=2)。/构造函数Matrix ()。/析构函数v

10、oid SetMatrix (double *rmax)。 /矩阵赋初值。class Linequ:public Matrix/公有派生类 Linequ 声明。经过公有派生, Linequ 类获得了除构造函数、析构函数之外的 Matrix 类的全部成员,由于基类的成员是公有和保护类型,因此在派生类中的成员函数 中,基类继承来的成员全部可以访问,而对于建立 Linequ 类对象的外部模块来 讲,基类的保护成员是无法访问的。通过保护访问类型和公有的继承方式,实 现了基类 Matrix 的数据的有效共享和可靠保护。在程序中,方程的系数矩阵、 解以及右端项全部采用了动态内存分配技术,这些工作都是在基类

11、、派生类的构造函数中完成,它们的清理工作在析构函数中完成。void PrintM ()。protected:int index。double* MatrixA 。/显示矩阵/方阵的行数 /矩阵存放数组首地址public:Linequ(int dims=2)。Linequ()。void SetLinequ (double *a, double *b) 。 voidPrintL () int Solve()。void ShowX ()private:double *sums。/外部接口/构造函数/析构函数/方程赋值double *solu。/显示方程/全选主元高斯消去法求解方程/显示方程的解/私有

12、数据/方程右端项/方程的解4.2类的实现/Linequ.cpp 文件,类实现#include linequ.h/包含类的声明头文件/Matrix 类的实现void Matrix:SetMatrix (double *rmatr)/ 设置矩阵for (int i=0。iindex*index。i+)MatrixAi=rmatri 。/矩阵成员赋初值Matrix:Matrix ( int dims)/矩阵 Matrix 类的构造函数index=dims。/矩阵行数赋值MatrixA=new doubleindex*index 。/动态内存分配Matrix:Matrix ()/矩阵 Matrix 类

13、的析构函数delete MatrixA 。/内存释放void Matrix:PrintM ()/显示矩阵元素coutThe Matrix is:endl 。for (int i=0。 iindex。 i+)for (int j=0。 jindex。 j+) cout* (MatrixA+i*index+j ) 。coutendl。/派生类 Linequ 的实现Linequ:Linequ (int dims) :Matrix (dims)/派生类 Linequ 的构造函数/使用参数调用基类构造函数sums=new doubledims。/动态内存分配solu=new doubledims。Lin

14、equ:Linequ ()/派生类 Linequ 的析构函数delete sums。/释放内存delete solu。void Linequ:SetLinequ( double *a,double *b)/ 设置线性方程组SetMatrix (a)。/调用基类函数for (int i=0。iindex。i+)sumsi=bi 。void Linequ:PrintL () /显示线性方程组coutThe line equation is:endl。for (int i=0。 iindex。 i+)for (int j=0。 jindex。 j+)cout* (MatrixA+i*index+j

15、) 。cout sumsiendl 。void Linequ:ShowX ()/输出方程组的解coutThe result is:endl 。for (int i=0。 iindex。 i+)coutXi=soluiendl。int Li n equ:Solve ( )/全选主元高斯法求解方程int *js,l,k,i,j,is,p,q 。double d,t。double *MatrixB 。 /声明局部矩阵 MatrixBMatrixB=new doubleindex*index 。/将矩阵 MatrixA 赋值给 MatrixB for (i=0。iindex*index。i+)Matr

16、ixBi=MatrixAi 。js=new intindex 。/分配动态内存l=1。for ( k=0。 k=index-2。 k+)/消去过程d=0.0。for ( i=k 。 i=index-1。 i+ )/选取主元素for ( j=k 。 jd) d=t 。 jsk=j 。 is=i。 if ( d+1.0=1.0)/主元素为零l=0。else/主元素交换if( jsk!=k )for( i=0。 i=index-1 。 i+)p=i*index+k 。 q=i*index+jsk 。t=MatrixBp 。MatrixBp=MatrixBqMatrixBq=t 。if( is!=k)

17、for( j=k 。 j=index-1。 j+ )p=k*index+j 。q=is*index+j 。t=MatrixBp 。 MatrixBp=MatrixBq 。MatrixBq=t 。t=sumsk 。 sumsk=sumsis。 sumsis=t。if (l=0 )/若主元素为零,求解失败deletejs。coutfailendl 。return 0。d=MatrixBk*index+k 。/归一化计算for (j=k+1 。 j=index-1 。 j+ )p=k*index+j 。MatrixBp=MatrixBp/d 。sumsk=sumsk/d。for (i=k+1 。 i

18、=index-1 。 i+ )/消去计算for (j=k+1。jv=index-1。j+)p=index*i+j 。MatrixBp=MatrixBp-MatrixBi*index+k*MatrixBk*index+j 。sumsi=sumsi-MatrixBi*index+k*sumsk 。d=MatrixB (index-1)*index+index-1 。if(fabs(d)+1.0=1.0)delete js。coutfail=0。-)t=0.0。for ( j=i+1 。 j=0。 k- )if( jsk!=k )t=soluk 。 soluk=solujsk 。 solujsk=t

19、 。delete js。return 1。在类的成员函数实现过程中, 派生类的构造函数使用参数调用了基类的构 造函数,为矩阵动态分配了内存空间。而派生类的析构函数同样也调用了基类 的析构函数,只是整个调用过程中完全是由系统内部完成。基类的保护数据成 员,经过公有派生之后,在派生类中是以保护成员的身份出现的,派生类的成 员函数可以自由地进行访问。全选主元高斯消去法求解函数返回值为整数,正常完成之后,返回值为 1,非正常结束后,返回值为0,根据函数的返回值,就可以判断求解过程的完成情况。4.3主函数设计/main.cpp 主函数#include linequ.h int main()/主函数dou

20、ble a=0.2368,0.2471,0.2568,1.2671,0.1968,0.2071,1.2168,0.2271,0.1581,1.1675,0.1768,0.1871,1.1161,0.1254,0.1397,0.1490。double b4= 1.8471,1.7471,1.6471,1.5471。/ 方程右端项Linequ equ1(4)。 /定义一个四元方程组对象 return 1。在程序的主函数部分,选择了一个四元方程组作为一个实际例子来验证算 法。方程组的系数及右端项数据都使用一维数组来存储。 首先定义一个四元方 程组对象 equl,在定义过程中调用派生类的构造函数,通过

21、派生类的构造函 数,又调用了基类的构造函数,对进一步求解动态分配了内存。接着给方程组 的系数和右端项赋初值,把我们选定的方程组输入到新定义的方程组对象 equ1 中。对象成员函数 PrintL 、Solve 和ShowX 分别完成了输出方程组、求解方程 组和输出求解结果的任务。5 DOS 界面程序运行结果及分析5.1程序运行结果程序运行结果如图 2 所示图2程序运行结果从图 2 中可以看出,程序能够实现全选主元高斯消去法对于线性方程组的 求解,/系数矩阵equ1.SetLinequ( a,b)。equ1.PrintL()。if (equ1.Solve()equ1.ShowX()。elsecou

22、tFailendl/设置方程组/输出方程组/求解方程组/输出方程组的解/求解失败但是,对于求解结果的正确性问题却无法获知,为了能够验证求解结果 的正确性,考虑将求解结果 x 带入原方程 Ax=b 中,如果满足原方程,即说明 求解结果是正确的,否则,说明求解存在问题,需对程序进行进一步调试分 析。为此,考虑在 Linequ 类中增加测试函数 Test,用以验证求解结果的正确 性。void Linequ:test()/求解结果验证函数double *b2。b2=new doubleindex。for (int i=0。iindex。i+)将解 solu 带入原方程求出新的右端项 b2b2i=0 。

23、for (int j=0。 jindex。 j+) b2i=b2i+MatrixAi*index+j*soluj 。for (i=0。 iindex。 i+) /输出新的右端项coutb2i 。coutendl。在主函数 main 中增加语句:equ1.test()。/验证求解结果经过验证的程序运行结果如图 3 所示。图3程序运行结果的验证从图 3 中可以看出,方程组求解验证的右端项结果与原右端项结果完全一 致,这说明了方程组求解的正确性。5.2运行结果分析整个程序中的矩阵存储采用的是一维数组和动态内存分配方式。基类是专门处理矩阵的类,公有派生类 Linequ 是针对线性方程组而设计 的,除了

24、继承基类的基本特征之外,结合问题的实际需要,增加了很多线性方 程组所特有的成员,使基类 Matrix 进一步具体化、特殊化,达到对问题的有效 描述和处理。程序的访问控制也是根据问题的需要而设计的。基类的数据成员的存储、 维护着矩阵数据,这正是派生类方程组的系数矩阵,使派生类解方程成员函数 必须访问的。利用保护成员特征,将基类数据成员的访问控制属性设置为保护 型,在公有派生类Linequ 中就可以访问到基类继承下来的保护成员;而对于类 外的其余模块,这些数据无法访问。这样,就在数据的共享与隐藏之间寻找到 一个比较恰当的结合点。在派生过程中,基类的构造函数和析构函数无法继承下来,因此在派生类 中需

25、要添加构造函数、析构函数来完成派生类的初始化和最后清理工作。派生 类的构造函数通过调用基类的构造函数来对基类数据进行初始化,本设计中, 派生类 Linequ 的构造函数调用了基类 Matrix 的构造函数并传递必须的初始化参 数。派生类的析构函数调用基类的构造函数,共同完成清理任务。6 基于 MFC 的图形界面程序开发MFC 的图形界面程序设计可在上述类设计的基础上进行改造, MFC 的图形 界面程序与 DOS 界面程序的主要不同点是: MFC 图形界面程序与 DOS 界面程 序的输入输出方式不同,DOS 界面程序采用字符交互式实现数据输入输出,主 要通过 cin,cout 等 I/O 流实现

26、,而 MFC 的图形程序界面采用标准 Windows 窗 口和控件实现输入输出,因此必须在 MFC 类的框架下加入上面所设计的矩阵和 方程组类,并通过图形界面的输入输出改造来完成。6.1基于MFC的图形界面程序设计(1)界面设计首先在 VC 中建立 MFC AppWizard(exe)工程,名称为 GuassLineGUI, 并在向导的 Step1 中选择 Dialog based,即建立基于对话框的应用程序,如下图 45 所示。F 面是编写代码的重要阶段,可以借鉴在设计基于DOS 界面的控制台应用图4建立MFC AppWizard(exe)工程图5建立基于对话框的应用程序将对话框资源中的默认

27、对话框利用工具箱改造成如下界面,如图6 所示。图6方程组求解程序界面设计图 6 所示的界面中包含了 3 个 Static Text 控件,3 个 Button 控件,和 24 个Edit Box 控件,控件的基本信息列表如下表 1 所示表1控件基本信息控件类别控件ID控件Caption说明Static TextIDC_STATIC系数矩阵A方程组右端项b解XBott onIDC BUTTON Read读入数据IDC BUTTON CALC计算求解IDC BUTTON Exit退出Edit BoxIDC_EDIT_A00 IDC_EDIT_A33矩阵A的16个元素IDC EDIT bO IDC

28、EDIT b3向量b的4个兀素IDC EDIT XO IDC EDIT X3解X的4个元素(2)代码设计为了能够将对话框界面上的控件能够与代码联系起来,需要为24 个 EditBox 控件建立 Member Variables,按 Ctrl+w 键进入 MFC ClassWizard 界面,选择Member Variables 选项卡,可显示成员变量设置界面,如图7 所示。图7成员变量设置界面通过该界面设置与 24 个 Edit Box 控件对应的成员变量,具体如表 2 所示表2控件基本信息控件ID成员变量类型成员变量名称IDC EDIT A00 IDC EDIT A33doublem A00

29、m A33IDC EDIT b0 IDC EDIT b3doublem b0m b3IDC EDIT X0 IDC EDIT X3doublem X0m X3程序的代码,并将其作必要的改写,具体改写的步骤与内容如下。1将 Linequ.h 文 件 和 Linequ.cpp 文 件 合 并 成 一 个 文 件 , 重 新 命名 为Linequ.h,并将其加入 MFC 工程。2修改 Linequ.h 文件具体包括:将显示矩阵 PrintM ()函数和显示方程 PrintL ()函数注释掉,因为在图形界面的程序上已经不需要连个函数承担输出功能了; 将输出方程组的解 ShowX() 函数加入参数 do

30、uble x 变成 ShowX( double x ),以实现将所求的解输出至参数 x 中,并最终完成在对 话框界面上的显示;将全选主元高斯法求解函数 Solve() 中的两处 cout 语句去掉,因为 不需要也不能够使用 cout 流实现输出。3在 对 话 框 类 的 实 现 文 件 GuassLineGUIDlg.cpp 中 加 入 #includeLinequ.h ,以实现在该文件中可使用 Linequ 类。4在 GuassLineGUIDlg.cpp 文件中 加入 以下全局 变量 的定 义, 以实现GuassLineGUIDlg 类和 Linequ 类之间的通信,具体代码如下:doub

31、le a=/系数矩阵0.2368,0.2471,0.2568,1.2671,0.1968,0.2071,1.2168,0.2271,0.1581,1.1675,0.1768,0.1871,1.1161,0.1254,0.1397,0.1490。double b4= 1.8471,1.7471,1.6471,1.5471。/方程右端项double *X 。/存放方程组的解5编写读入数据按钮的消息处理函数,实现将矩阵和右端项的数据刷新到界面上,具体代码如下:void CGuassLineGUIDlg:OnBUTTONRead()/ TODO: Add your control notificati

32、on handler code herem_A00=a0 。 m_A01=a1 。 m_A02=a2 。 m_A03=a3 。m_A10=a5 。 m_A11=a6 。 m_A12=a7 。 m_A13=a8 。 m_A20=a9 。m_A21=a10 。 m_A22=a11 。 m_A23=a12 。 m_A30=a13 。m_A31=a14 。 m_A32=a15 。 m_A33=a16 。 m_b0=b0 。 m_b1=b1 。m_b2=b2 。 m_b3=b3 。UpdateData(FALSE)o退出按钮比较简单,代码如下:void CGuassLineGUIDlg:OnBUTTONExit ()/ TODO: Add your control notification handler code here OnOK()。6.2程序测试运行程序后,首先出现的界面如图 8 所示。图8程序初始运行界面单击读入数据按钮后,可将系数矩阵 A 和方程组右端项 b 的数据在界面上编写计算求解按钮的消息处理函数,实现将方程求解,具体代码如下:void CGuassLineGUIDlg:OnButtonCalc ()/

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论