面向对象课设范例通信工程最终Word格式.docx
《面向对象课设范例通信工程最终Word格式.docx》由会员分享,可在线阅读,更多相关《面向对象课设范例通信工程最终Word格式.docx(22页珍藏版)》请在冰豆网上搜索。
![面向对象课设范例通信工程最终Word格式.docx](https://file1.bdocx.com/fileroot1/2022-11/25/4cab2978-9b9c-47bb-9419-10beedd37b4e/4cab2978-9b9c-47bb-9419-10beedd37b4e1.gif)
对于k从0开始到n-2结束,进行以下三步:
(1)首先,从系数矩阵A的第k行、k列开始的子矩阵中选取绝对值最大的元素作为主元素,例如:
(5)
然后交换B的第k行与第i1行,第k行与第j1列,这样,这个子矩阵中的具有最大绝对值的元素被交换到第k行、k列的位置。
(2)其次,进行归一化计算。
计算方法为:
(6)
(3)最后,进行消去运算:
(7)
第二步,回代过程。
(8)
在这里,只是列出简要地给出了全选主元高斯消去法的算法步骤,具体推导及详细过程可参考数值分析方面的有关资料。
2.2开放地址法基本思想
当发生地址冲突时,按照某种方法继续探测哈希表中的其他存储单元,直到找到空位置为止。
这个过程可用下式描述:
采用这种方法时,首先计算出元素的直接哈希地址,如果该存储单元已被其他元素占用,则继续查看地址为的存储单元,如此重复直至找到某个存储单元为空时,将关键字为key的数据元素存放到该单元。
增量d可以有不同的取法,并根据其取法有不同的称呼。
3类设计
3.1类的概述
类模板就是设计一种类的框架,可以适用不同的数据类型,只是一种类的抽象,因此,利用类模板可以针对不同的数据类型定义出具有共性的一组类。
定义形式如下:
template<
类型名参数名1,类型名参数名2,…>
class类名
{
类声明体;
};
与函数模板类似,通过使用类模板可以使得所定义的类中的某些数据成员某些成员函数的参数某些成员函数的返回值都可以是任意的数据类型(包括基本类型和自定义类型)。
所以,可以通过类模板将程序所处理的对象的类型参数化,从而使得同一段程序可用于处理多种不同类型的对象,提高了程序的抽象层次和可重用性。
由于哈希表中的数据元素可以是char,int,float等多种数据类型,因此可以使用类模板来构造本程序的实现框架。
本设计面临的计算问题的关键是矩阵运算。
可以定义一个矩阵类Matrix作为基类,然后由矩阵类派生出线性方程组类Linequ。
矩阵类Matrix只处理n×
n类型的方阵,方阵用一个一维数组来存放,矩阵类Matrix的数据成员包括数组的首地址和n,矩阵类Matrix的功能有设置矩阵的值SetMatrix()和显示矩阵PrintM()等。
从问题的需要来看,线性方程组类Linequ的数据除了由矩阵类Matrix继承过来用于存放系数矩阵A的成员外,还应该包括存放解向量x和方程右端向量b的数组首地址。
线性方程组类Linequ的主要操作有设置SetLinequ()、显示PrintL()、求解Solve()及输出方程的解showX()。
可以通过定义线性方程组类Linequ的新增成员函数来实现这些针对方程组求解的功能。
在线性方程组的求解过程中,在线性方程组类Linequ的成员函数Solve中需要访问基类矩阵类Matrix的数据成员,利用公有继承方式派生,同时将Matrix类中的数据成员的访问控制设置为保护类型。
这样,经过公有派生之后,基类的保护成员在派生类中依然是保护成员,可以被派生类的成员函数访问。
整个类分别使用了insert(t1key,t2data)实现哈希表元素的插入,remove(t1key)实现哈希表元素的删除,query(t1key)实现哈希表元素的查找,display()实现哈希表元素的显示。
3.2类的接口设计
//Linequ.h文件,实现类的声明
#include<
iostream>
cmath>
usingnamespacestd;
classMatrix//基类Matrix声明
{
public:
//外部接口
Matrix(intdims=2);
//构造函数
~Matrix();
//析构函数
voidSetMatrix(double*rmax);
//矩阵赋初值
voidPrintM();
//显示矩阵
protected:
intindex;
//方阵的行数
double*MatrixA;
//矩阵存放数组首地址
};
classLinequ:
publicMatrix//公有派生类Linequ声明
//外部接口
Linequ(intdims=2);
~Linequ();
voidSetLinequ(double*a,double*b);
//方程赋值
voidPrintL();
//显示方程
intSolve();
//全选主元高斯消去法求解方程
voidShowX();
//显示方程的解
private:
//私有数据
double*sums;
//方程右端项
double*solu;
//方程的解
经过公有派生,Linequ类获得了除构造函数、析构函数之外的Matrix类的全部成员,由于基类的成员是公有和保护类型,因此在派生类中的成员函数中,基类继承来的成员全部可以访问,而对于建立Linequ类对象的外部模块来讲,基类的保护成员是无法访问的。
通过保护访问类型和公有的继承方式,实现了基类Matrix的数据的有效共享和可靠保护。
在程序中,方程的系数矩阵、解以及右端项全部采用了动态内存分配技术,这些工作都是在基类、派生类的构造函数中完成,它们的清理工作在析构函数中完成。
3.3类的实现
template<
classt1,classt2>
//构造函数的实现
hash<
t1,t2>
:
hash(){
array=newlinknode[7];
for(inti=0;
i<
7;
i++){
array[i]=NULL;
}
~hash(){
for(inti=0;
if(array[i]!
=NULL){
linknoden=array[i];
while(n!
linknoden1=n;
n=n->
next;
deleten1;
}
//插入元素的函数
voidhash<
insert(t1key,t2data){
intsum=func(key)%7;
//派生类Linequ的实现
Linequ:
Linequ(intdims):
Matrix(dims)//派生类Linequ的构造函数
{//使用参数调用基类构造函数
sums=newdouble[dims];
//动态内存分配
solu=newdouble[dims];
}
~Linequ()//派生类Linequ的析构函数
delete[]sums;
//释放内存
delete[]solu;
}else{
ln*n=newln;
n->
key=key;
data=data;
next=NULL;
array[sum]=n;
//查询元素的函数实现
t2hash<
query(t1key){
intsum=func(key)%7;
linknodep=array[sum];
while(p){
if(type=="
char*"
){
if(stricmp((char*)(int)p->
key,(char*)(int)key)==0){cout<
<
"
关键字"
key<
的data值为:
endl;
returnp->
data;
p=p->
}elseif(type=="
void*"
if((int)p->
key==(int)key){cout<
if(p->
key==key){cout<
return"
您所查询的关键字在该哈希表中不存在!
;
template<
voidhash<
display()//显示哈希表元素的函数实现
{
i++)
{if(array[i]!
=NULL)
ln*n=array[i];
{
cout<
array["
]"
为"
n->
}
}elsecout<
为空!
}
//整型关键字哈希函数实现
inthash<
func(inti){
type="
int"
returni;
//浮点型模板
func(floati){
float"
ints=i*100;
returns;
//指向字符型指针关键字哈希函数实现
func(char*i){
ints=strlen(i)*i[0];
//字符型模板
func(chari){
char"
ints=(int)i;
}}
remove(t1key)//删除元素的哈希函数实现
{
linknodep=array[sum];
if(p!
{if(p->
next!
{if(p->
key==key)
{array[sum]=p->
deletep;
cout<
已被删除!
else
{while(p->
=NULL&
&
p->
next->
key!
=key)
linknodep2=p->
p->
next=p2->
deletep2;
else{array[sum]=NULL;
else{cout<
对不起!
您删除的关键字"
在本哈希表中不存在!
4基于控制台的应用程序
4.1主函数设计
//main.cpp主函数
#include"
linequ.h"
intmain()//主函数
doublea[]=//系数矩阵
{
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
};
doubleb[4]={1.8471,1.7471,1.6471,1.5471};
//方程右端项
Linequequ1(4);
//定义一个四元方程组对象
equ1.SetLinequ(a,b);
//设置方程组
equ1.PrintL();
//输出方程组
if(equ1.Solve())//求解方程组
equ1.ShowX();
//输出方程组的解
cout<
Fail"
//求解失败
return1;
在程序的主函数部分,选择了一个四元方程组作为一个实际例子来验证算法。
方程组的系数及右端项数据都使用一维数组来存储。
首先定义一个四元方程组对象equ1,在定义过程中调用派生类的构造函数,通过派生类的构造函数,又调用了基类的构造函数,对进一步求解动态分配了内存。
接着给方程组的系数和右端项赋初值,把我们选定的方程组输入到新定义的方程组对象equ1中。
对象成员函数PrintL、Solve和ShowX分别完成了输出方程组、求解方程组和输出求解结果的任务。
4.2运行结果及分析
程序初始化运行的结果如图1所示。
从图1中可以看出通过关键字的输入,锁定key和data,可以对哈希表进行数据的插入,并使哈希表数据重新初始化,实现数据的更新。
图1程序初始化运行结果
图2为经过插入操作后对数据的查询结果,由图2可以看出,——————————————————————————————————————————————————————————————————。
图2程序运行结果
如图进行删除操作,通过哈希表中关键字的索引进行数据的删除,删除的元素为哈希表中已经存在的元素。
图3程序运行结果
若删除的关键字在本哈希表中不存在则提示删除出错。
5基于MFC的应用程序
MFC的图形界面程序设计可在上述类设计的基础上进行改造,MFC的图形界面程序与DOS界面程序的主要不同点是:
MFC图形界面程序与DOS界面程序的输入输出方式不同,DOS界面程序采用字符交互式实现数据输入输出,主要通过cin,cout等I/O流实现,而MFC的图形程序界面采用标准Windows窗口和控件实现输入输出,因此必须在MFC类的框架下加入上面所设计的矩阵和方程组类,并通过图形界面的输入输出改造来完成。
5.1图形界面设计
首先在VC中建立MFCAppWizard(exe)工程,名称为GassineGU,并在向导的Step1中选择Dialogbased,即建立基于对话框的应用程序,如下图5~6所示。
图5建立MFCAppWizard(exe)工程
图6建立基于对话框的应用程序
将对话框资源中的默认对话框利用工具箱改造成如下界面,如图7所示。
图7方程组求解程序界面设计
图7所示的界面中包含了3个StaticText控件,3个Button控件,和2个EditBox控件,控件的基本信息列表如下表1所示。
表1控件基本信息
控件类别
控件ID
控件Caption
说明
StaticText
IDC_STATIC
系数矩阵A
方程组右端项b
解X
Botton
IDC_BUTTON_Read
读入数据
IDC_BUTTON_CALC
计算求解
IDC_BUTTON_Exit
退出
EditBox
IDC_EDIT_A00~IDC_EDIT_A33
矩阵A的16个元素
IDC_EDIT_b0~IDC_EDIT_b3
向量b的4个元素
IDC_EDIT_X0~IDC_EDIT_X3
解X的4个元素
5.2程序代码设计
为了能够将对话框界面上的控件能够与代码联系起来,需要为24个EditBox控件建立MemberVariables,按Ctrl+w键进入MFCClassWizard界面,选择MemberVariables选项卡,可显示成员变量设置界面,如图8所示。
图8成员变量设置界面
下面是编写代码的重要阶段,可以借鉴在设计基于DOS界面的控制台应用程序的代码,并将其作必要的改写,具体改写的步骤与内容如下。
//Haxibiao.cpp:
implementationfile
//
类
#ifdef_DEBUG
#definenewDEBUG_NEW
#undefTHIS_FILE
staticcharTHIS_FILE[]=__FILE__;
#endif
char*,char*>
h;
//将实例化的hash类对象声明为全局的以便以下函数使用
/////////////////////////////////////////////////////////////////////////////
//CAboutDlgdialogusedforAppAbout
classCAboutDlg:
publicCDialog
CAboutDlg();
//DialogData
//{
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DE
BEGIN_MESSAGE_MAP(CAboutDlg,CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
//Nomessagehandlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
//CWANGDlgdialog
CWANGDlg:
CWANGDlg(CWnd*pParent/*=NULL*/)
:
CDialog(CWANGDlg:
IDD,pParent)
{xGetApp()->
LoadIcon(IDR_MAINFRAME);
voidCWANGDlg:
DoDataExchange(CDataExchange*pDX)
CDialog:
DoDataExchange(pDX);
//{{AFX_DATA_MAP(CWANGDlg)
DDX_Text(pDX,IDC_EDIT1,m_HX);
DDX_Text(pDX,IDC_EDIT2,m_key);
DDX_Text(pDX,IDC_EDIT3,m_data);
//}}AFX_DATA_MAP
BEGIN_MESSAGE_MAP(CWANGDlg,CDialog)
//{{AFX_MSG_MAP(CWANGDlg)
ON_WM_SYSCOMMAND()
ON_W/////////////////////////////////////////////////////////////////////////////
//CWANGDlgmessagehandlers
BOOLCWANGDlg:
OnInitDialog()
OnInitDialog();
h.insert("
sds"
"
etew"
);
//初始化哈希表
h.insert("
n25"
45"
4.5765k"
2"
$345"
6"
43.r"
55"
yan"
24"
h.display();
//h对象调用display()函数以显示哈希表元素
m_HX=h.str;
UpdateData(0);
//在编辑框处显示哈希表元素
//Add"
About..."
menuitemtosystemmenu.
//IDM_ABOUTBOXmustbeinthesystemcommandrange.
Menu->
AppendMenu(MF_SEPARATOR);
pSysMenu->
AppendMenu(MF_STRING,IDM_ABOUTBOX,strAboutMenu);
}
if((nID&
0xFFF0)==IDM_ABOUTBOX)
CAboutDlgdlgAbout;
dlgAbout.DoModal();
CDialog:
OnSysCommand(nID,lParam);
//Ifyouaddaminimizebuttontoyourdialog,youwillneedthecodebelow
//todrawtheicon.ForMFCapplicationsusingthedocument/viewmodel,
//thisisautomaticallydoneforyo