《C++课程设计字符串类的设计与实现.doc》由会员分享,可在线阅读,更多相关《C++课程设计字符串类的设计与实现.doc(30页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、Four short words sum up what has lifted most successful individuals above the crowd: a little bit more.-author-dateC+课程设计字符串类的设计与实现C+课程设计字符串类的设计与实现封 皮(按学校要求手工填写)课 程 设 计 任 务 书学院信息科学与工程专业通信工程学生姓名*学号10030603*设计题目字符串类的设计与实现内容及要求:计算机处理的对象分为数值数据和非数值数据,字符串是最基本的非数值数据。其应用非常广泛,它是许多软件系统(如字符编辑、情报检索、词法分析、符号处理、自然
2、语言翻译等系统)的操作对象。其重要性不言而喻。要求采用C+语言实现进行字符串类的设计,具体要求如下:(1)使用堆分配存储表示实现字符串的存储;(2)实现串赋值操作StrAssign(&T, chars);(3)实现串比较操作StrCompare(S,T);(4)实现求串长操作StrLength(S);(5)实现串连接操作Concat(&T,S1,S2)(6)实现求子串操作SubString(&Sub,S,pos,len)(7)实现清空子串操作ClearString(&S);(8)将上述功能作为类的成员函数实现,编写主函数测试上述功能。进度安排:第17周:分析题目,查阅课题相关资料,进行类设计、
3、算法设计;第18周:程序的设计、调试与实现;第19周:程序测试与分析,撰写课程设计报告,进行答辩验收。指导教师(签字):年 月 日学院院长(签字)年 月 日目 录1 需求分析- 1 -2 算法基本原理- 1 -3 类设计- 2 -4 详细设计- 3 -4.1 类的接口设计- 3 -4.2 类的实现- 5 -4.3 主函数设计- 10 -5 DOS界面程序运行结果及分析- 11 -5.1 程序运行结果- 11 -5.2运行结果分析- 12 -6 基于MFC的图形界面程序开发- 13 -6.1 基于MFC的图形界面程序设计- 13 -6.2 程序测试- 17 -6.3 MFC程序编写总结- 19
4、-7 参考文献- 19 -1 需求分析(1) 计算机处理的对象分为数值数据和非数值数据,字符串是最基本的非数值数据。其应用非常广泛,它是许多软件系统(如字符编辑、情报检索、词法分析、符号处理、自然语言翻译等系统)的操作对象。其重要性不言而喻。(2)字符串是字符的有限集合,可记作a=a1 an。其中a是字符串的名,单括号里的字符序列是字符串的值,单引号不是字符串的成分,其作用是为了避免变量名与常量混淆。ai(0i0,如果等于0,则称a为空串,记作:a=。 2 算法基本原理(1)字符串从结构上看是一种以字符为数据元素的线性表,从存储结构的不同可分为顺序表和链式存储结构,它们都适用于字符串,但由于要
5、求的操作不同,为了提高运算效率所选用的存储结构也是不同的。对于字符串改动较频繁的一般用链式存储结构,而顺序存储结构能够高效的读取。所以各有优点。本程序由于需要大量改动数据,理所当然的选择链式存储结构,其算法结构为: Typedef structChar *ch; /*若字符串为空,则按长度分配存储区,否则为NULL */Int length; /*字符串的长度*、(2)本题字符串要求用堆来分配字符串的存储空间,采用堆分配函数malloc,它的格式为T-ch=(char *)malloc(sizeof(char)*len,就会为字符串分配内存。(3)函数是有字符串类进行调用的,通过在主函数中定义
6、字符串类的对象,作为函数的参数,对于需要改写对象的需要进行址传递,我们可以通过函数在主函数中的反映来观察他的执行状态。3 类设计4 详细设计整个程序分为三个独立的文档,Linequ.h文件中包括矩阵类Matrix和线性方程组类Linequ的声明,Linequ.cpp文件中包括这两个类的成员函数实现文件;main.cpp文件包括程序的主函数,主函数中定义了一个类Linequ的对象,通过这个对象求解一个四元线性方程组。4.1 类的接口设计/Linequ.h文件,实现类的声明#include #include using namespace std;class Matrix/基类Matrix声明pu
7、blic:/外部接口Matrix(int dims=2);/构造函数Matrix();/析构函数void SetMatrix(double *rmax);/矩阵赋初值void PrintM();/显示矩阵protected:int index;/方阵的行数double* MatrixA;/矩阵存放数组首地址;class Linequ:public Matrix/公有派生类Linequ声明public:/外部接口Linequ(int dims=2);/构造函数Linequ();/析构函数void SetLinequ(double *a, double *b);/方程赋值void PrintL()
8、;/显示方程int Solve();/全选主元高斯消去法求解方程void ShowX();/显示方程的解private:/私有数据double *sums;/方程右端项double *solu;/方程的解;经过公有派生,Linequ类获得了除构造函数、析构函数之外的Matrix类的全部成员,由于基类的成员是公有和保护类型,因此在派生类中的成员函数中,基类继承来的成员全部可以访问,而对于建立Linequ类对象的外部模块来讲,基类的保护成员是无法访问的。通过保护访问类型和公有的继承方式,实现了基类Matrix的数据的有效共享和可靠保护。在程序中,方程的系数矩阵、解以及右端项全部采用了动态内存分配技
9、术,这些工作都是在基类、派生类的构造函数中完成,它们的清理工作在析构函数中完成。4.2 类的实现4.3 主函数设计int main()int a=1,p,len; MyString S; MyString st1; MyString st2; MyString sub; MyString T; char ch120; char cl; cout*欢迎进入字符串操作程序*endl;while (a!=0) cout-endl;cout请选择功能操作:endl;coutn1.字符串的赋值n2.字符串的长度n3.字符串的比较n4.字符串的连接n5.求字符串的子串n6.清空字符串n0.退出a; swi
10、tch(a)case 0:cout*谢谢使用!祝您工作顺利!*endl;break;case 1: cout请输入用于赋值新字符串ch1; InitString(&st1); StrAssign(&st1,ch1);cout字符串被赋的值为:; PrintString(st1);break ;case 2: cout请输入新字符串Sch1; InitString(&st1); StrAssign(&st1,ch1); cout长度为:StrLength(st1)endl;break;case 3: cout请输入要比较的两个字符串S pk Tendl; cout请输入第一个字符串st1(长度c
11、h1; InitString(&st1); StrAssign(&st1,ch1); cout请输入第二个字符串st2(长度ch1; InitString(&st2); StrAssign(&st2,ch1); StrCompare(st1,st2); int flag=StrCompare(st1,st2); if(flag=0) cout字符串st1与st2相等0) cout字符串st1比st2大endl; else cout字符串st1比st2小endl; break ; case 4:cout请输入要连接的两个字符串S1 & S2endl; cout请输入第一个字符串(长度ch1; I
12、nitString(&st1); StrAssign(&st1,ch1); cout请输入第二个字符串(长度ch1; InitString(&st2); StrAssign(&st2,ch1); InitString(&T);Concat(&T,st1,st2);cout连接后的新字符串:endl;PrintString(T);break; case 5:cout请输入主串S(长度20):ch1; InitString(&S); StrAssign(&S,ch1); InitString(&sub); cout请输入起始位置p:p; cout请输入子串的长度len(请考虑主串的长度)len;
13、cout所求子串为:endl; SubString(&sub,S,p,len); PrintString(sub); break;case 6:cout确定要清空的字符串(Y/N)cl;if(cl=y|cl=Y) ClearString(&st1); ClearString(&st2); ClearString(&sub); ClearString(&T);cout字符串操作清除成功!endl;break;default:cout操作错误!请输入正确序号!endl; ; return 0;主函数的设计思路是通过定义mystring类的对象,然后通过生成的对象去调用相应的函数从而达到调试所编写的
14、函数功能的目的。此主函数有着演示函数的要求,为了使它能够更灵活的进行函数的调用,首先设计了一个循环体,由整型变量a控制,当a=0时就结束循环。而在循环体中又由switch(a)函数来控制,通过输入不同的a的值来控制不同的操作,即函数的演示。5 DOS界面程序运行结果及分析从它运行的界面可以看出,当进入函数调试状态时我们可也通过输入相应的操作序号来选择不同的操作。例如选择输入1将进入字符串的赋值操作。下面就来看一下相应的函数。输入1点回车键就被要求输入要赋得值,函数原型为StrAssign(&T, chars),执行后就把字符串chars赋给对象T了。输入2则进入字符串的长度函数,我们要测试它的
15、功能只要输入一个字符串就可以加以验证。例如上图所示输入字符串为:sfdffgffh,则串长为9.选择4则进行字符串的比较功能,这个函数需要读取相比较的两个字符串,通过对字符串的每个字符的逐个的比较有一个返回值返给调用函数。选择4则进行字符串的连接功能,把一个字符串连在另一个字符串的后面,如上图所示:第一个字符串为dfghgh,另一个字符串为fgghf,则连接的字符串为dfghghfgghf。输入5则选择求字符串子串的功能,这个函数需要输入一个主串,起始位置p和子串长度len,输入好参数后就可输出所求的子串了。因为上述字符串操作中都给字符串赋了值,所以需要字符串,回到初始状态。选择0则结束函数演
16、示。5.1 程序运行结果图2 程序运行结果从图2中可以看出,程序能够实现全选主元高斯消去法对于线性方程组的求解,但是,对于求解结果的正确性问题却无法获知,为了能够验证求解结果的正确性,考虑将求解结果x带入原方程Ax=b中,如果满足原方程,即说明求解结果是正确的,否则,说明求解存在问题,需对程序进行进一步调试分析。为此,考虑在Linequ类中增加测试函数Test,用以验证求解结果的正确性。void Linequ:test()/求解结果验证函数double *b2;b2=new doubleindex;for (int i=0;iindex;i+)/将解solu带入原方程求出新的右端项b2b2i=
17、0;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是针对线性方程组而设计的,除了继承基类的基本特征之外,结合
18、问题的实际需要,增加了很多线性方程组所特有的成员,使基类Matrix进一步具体化、特殊化,达到对问题的有效描述和处理。程序的访问控制也是根据问题的需要而设计的。基类的数据成员的存储、维护着矩阵数据,这正是派生类方程组的系数矩阵,使派生类解方程成员函数必须访问的。利用保护成员特征,将基类数据成员的访问控制属性设置为保护型,在公有派生类Linequ中就可以访问到基类继承下来的保护成员;而对于类外的其余模块,这些数据无法访问。这样,就在数据的共享与隐藏之间寻找到一个比较恰当的结合点。在派生过程中,基类的构造函数和析构函数无法继承下来,因此在派生类中需要添加构造函数、析构函数来完成派生类的初始化和最后
19、清理工作。派生类的构造函数通过调用基类的构造函数来对基类数据进行初始化,本设计中,派生类Linequ的构造函数调用了基类Matrix的构造函数并传递必须的初始化参数。派生类的析构函数调用基类的构造函数,共同完成清理任务。6 基于MFC的图形界面程序开发MFC的图形界面程序设计可在上述类设计的基础上进行改造,MFC的图形界面程序与DOS界面程序的主要不同点是:MFC图形界面程序与DOS界面程序的输入输出方式不同,DOS界面程序采用字符交互式实现数据输入输出,主要通过cin,cout等I/O流实现,而MFC的图形程序界面采用标准Windows窗口和控件实现输入输出,因此必须在MFC类的框架下加入上
20、面所设计的矩阵和方程组类,并通过图形界面的输入输出改造来完成。6.1 基于MFC的图形界面程序设计(1)界面设计首先在VC中建立MFC AppWizard(exe)工程,名称为GuassLineGUI,并在向导的Step1中选择Dialog based,即建立基于对话框的应用程序,如下图45所示。图4 建立MFC AppWizard(exe)工程图5 建立基于对话框的应用程序将对话框资源中的默认对话框利用工具箱改造成如下界面,如图6所示。图6 方程组求解程序界面设计图6所示的界面中包含了3个Static Text控件,3个Button控件,和24个Edit Box控件,控件的基本信息列表如下表
21、1所示。表1 控件基本信息控件类别控件ID控件Caption说明Static TextIDC_STATIC系数矩阵A方程组右端项b解XBottonIDC_BUTTON_Read读入数据IDC_BUTTON_CALC计算求解IDC_BUTTON_Exit退出Edit BoxIDC_EDIT_A00 IDC_EDIT_A33矩阵A的16个元素IDC_EDIT_b0 IDC_EDIT_b3向量b的4个元素IDC_EDIT_X0 IDC_EDIT_X3解X的4个元素(2)代码设计为了能够将对话框界面上的控件能够与代码联系起来,需要为24个Edit Box控件建立Member Variables,按Ct
22、rl+w键进入MFC ClassWizard界面,选择Member Variables选项卡,可显示成员变量设置界面,如图7所示。图7 成员变量设置界面通过该界面设置与24个Edit Box控件对应的成员变量,具体如表2所示。表2 控件基本信息控件ID成员变量类型成员变量名称IDC_EDIT_A00 IDC_EDIT_A33doublem_A00m_A33IDC_EDIT_b0 IDC_EDIT_b3doublem_b0m_b3IDC_EDIT_X0 IDC_EDIT_X3doublem_X0m_X3下面是编写代码的重要阶段,可以借鉴在设计基于DOS界面的控制台应用程序的代码,并将其作必要的改
23、写,具体改写的步骤与内容如下。将Linequ.h文件和Linequ.cpp文件合并成一个文件,重新命名为Linequ.h,并将其加入MFC工程。修改Linequ.h文件具体包括:l 将显示矩阵PrintM()函数和显示方程PrintL()函数注释掉,因为在图形界面的程序上已经不需要连个函数承担输出功能了;l 将输出方程组的解ShowX()函数加入参数double x变成ShowX(double x),以实现将所求的解输出至参数x中,并最终完成在对话框界面上的显示;l 将全选主元高斯法求解函数Solve()中的两处cout语句去掉,因为不需要也不能够使用cout流实现输出。在对话框类的实现文件G
24、uassLineGUIDlg.cpp中加入#include Linequ.h,以实现在该文件中可使用Linequ类。在GuassLineGUIDlg.cpp文件中加入以下全局变量的定义,以实现GuassLineGUIDlg类和Linequ类之间的通信,具体代码如下:double 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;/方
25、程右端项double *X;/存放方程组的解编写读入数据按钮的消息处理函数,实现将矩阵和右端项的数据刷新到界面上,具体代码如下:void CGuassLineGUIDlg:OnBUTTONRead() / TODO: Add your control notification 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_
26、A32=a15; m_A33=a16;m_b0=b0; m_b1=b1; m_b2=b2; m_b3=b3;UpdateData(FALSE);编写计算求解按钮的消息处理函数,实现将方程求解,具体代码如下:void CGuassLineGUIDlg:OnButtonCalc() / TODO: Add your control notification handler code hereLinequ equ1(4);/定义一个四元方程组对象equ1.SetLinequ(a,b);/设置方程组X=new double4;if(equ1.Solve()/求解方程组equ1.ShowX(X);/输出
27、方程组的解m_X0=X0;m_X1=X1;m_X2=X2;m_X3=X3;UpdateData(FALSE);elseMessageBox(求解失败);/求解失败退出按钮比较简单,代码如下:void CGuassLineGUIDlg:OnBUTTONExit() / TODO: Add your control notification handler code hereOnOK();6.2 程序测试运行程序后,首先出现的界面如图8所示。图8 程序初始运行界面单击读入数据按钮后,可将系数矩阵A和方程组右端项b的数据在界面上显示出来,如图9所示。图9 读入数据后的界面单击计算求解按钮,实现求解并
28、将解显示出来,如图10所示。图10 求解方程组后的界面单击退出按钮后,程序能够正常实现退出。6.3 MFC程序编写总结MFC程序与DOS界面程序编写的最大不同是程序员需要将编程精力放在图形界面设计、图形界面输入输出以及界面元素和代码对应转换等问题上,而这些问题在DOS界面程序中是不存在的,因此,初学MFC的编程者会对此感到困难,然而,当你编写出一个基于Windows界面的程序时,所获得的满足程度远远大于简单的DOS界面程序,况且基于Windows的图形界面的程序设计已成为主流,作为程序员而言,是非学会不可的。本次课程设计作为编写Windows程序的初步尝试,能够实现程序的主要功能,可以说是取得
29、了成功,然而好的程序绝不仅仅是只有功能性这一个指标,本此编写的MFC程序虽然能实现所需功能,但从面向对象程序设计理念和图形界面设计要求来说,尚存在不足,主要包括以下几个方面。(1)使用全局变量存储矩阵系数、方程组右端向量和解向量本身有悖面向对象程序设计理念,需要将其改进,利用局部变量和其它方式实现存储,作者认为最理想的方式是使用文件。(2)将类的定义与实现放在同一个头文件Linequ.h中也违背了面向对象程序设计理念,需要将二者分开成定义文件和实现文件。(3)图10所示的界面中对解的显示没有格式化,导致界面看起来不够规范,需要对解的输出进行小数点固定位数显示。7 参考文献1徐士良. C常用算法程序集. 北京:清华大学出版社,19952郑莉,董渊,张瑞丰. C+语言程序设计(第3版). 北京:清华大学出版社,20073钱能. C+程序设计教程(第二版). 北京:清华大学出版社,20074陈志泊,王春玲. 面向对象的程序设计语言C+. 北京:人民邮电出版社,20025李庆扬,王能超,易大义. 数值分析. 湖北:华中理工大学出版社,1986
限制150内