gai2010级通信工程专业面向对象课程设计要求与指导11.doc

上传人:jian****018 文档编号:9671335 上传时间:2020-04-07 格式:DOC 页数:22 大小:211.50KB
返回 下载 相关 举报
gai2010级通信工程专业面向对象课程设计要求与指导11.doc_第1页
第1页 / 共22页
gai2010级通信工程专业面向对象课程设计要求与指导11.doc_第2页
第2页 / 共22页
gai2010级通信工程专业面向对象课程设计要求与指导11.doc_第3页
第3页 / 共22页
点击查看更多>>
资源描述
课 程 设 计 任 务 书 学院 信息科学与工程 专业 通信工程 学生姓名 学号 设计题目 静态查找类模板的设计与实现 内容及要求 在非数值运算问题中 数据存储量一般很大 为了在大量信息中找到某些 值 就需要用到查找技术 基于线性表的查找具体可分为顺序查找 折半查找 和分块查找 折半查找又分为递归和非递归两类 要求采用 C 语言 建立一维数组数据结构的模板类 使一维数组中的数 据元素可以是 char int float 等多种数据类型 并对数组元素进行静态查找 主 要完成如下功能 1 实现数组数据的输入和输出 2 对数组进行顺序查找 3 对有序数组进行折半查找 递归算法 4 对有序数组进行折半查找 非递归算法 5 将每种查找功能作为类的成员函数实现 编写主函数测试上述查找 功能 进度安排 第 17 周 分析题目 查阅课题相关资料 进行类设计 算法设计 第 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 7 参考文献 19 1 需求分析 1 查找运算在实际生活中使用频率高 如帐户查询 订票查询及股市查 询等 一些实时查询系统的效率也格外重要 2 假定被查找的对象是由一组结点 元素 组成的表或文件 而每个结 点则由若干个数据项组成 所谓的查找 即给定一个待查数据值 在表的指定 数据项中查找等于待查数据值的结点 若找到 则查找成功 返回该结点的信 息或该结点在表中的位置 否则查找失败 返回相关提示信息 3 静态查找表查找方式包括顺序查找 折半查找 递归和非递归 2 算法基本原理 1 顺序查找 在查找的存储方式中 顺序表是最简单的一种 建立在其上的顺序查找是从 表的一端开始 顺序扫描 依次将扫描到的元素和待查数值比较 若当前元素 的数据值与待查数据值相等 则查找成功 若扫描结束后 仍未找到数据值等 于待查数据值的元素 则查找失败 顺序查找实例如下图 顺序表的顺序查找 当前顺序表如下 0 1 2 3 4 71 68 74 17 20 请输入要查找的元素 74 查找经过如下 第一趟顺序查找的结果为 0 1 2 3 4 71 68 74 17 20 第二趟顺序查找的结果为 0 1 2 3 4 71 68 74 17 20 第三趟顺序查找的结果为 0 1 2 3 4 71 68 74 17 20 查找结果 你要查找的元素 74 是第 3 个元素 2 折半查找 1 非递归折半查找 折半查找是一种效率较高的查找方法 但要求作用于有序顺序表 其基本 思想是 最初把整个有序顺序表作为查找区域 每次用待查数据值与查找区域 中间元素比较 分以下三种情况处理 如果待查数据值等于中间元素 则查找 成功 如果待查数据值小于中间元素 则继续在前半区域查找 如果待查数据 值大于中间元素 则继续在后半区域查找 查找过程中 每次与中间元素比较 就可以确定查找是否成功 如不成功 则当前查找区域缩小一半 这样查找区域逐渐缩小 如果查找区域最终缩小到 不存在 则表示查找不到这个数据 非递归折半查找实例 非递归折半查找 当前有序顺序表如下 0 1 2 3 4 5 6 9 18 26 27 29 32 40 请输入要查找的元素 26 查找经过如下 第 1 趟折半查找结果为 0 1 2 3 4 5 6 9 18 26 27 29 32 40 第 2 趟折半查找结果为 0 1 2 3 4 5 6 9 18 26 27 29 32 40 第 3 趟折半查找结果为 0 1 2 3 4 5 6 9 18 26 27 29 32 40 查找结果 你要查找的元素 26 是第 3 个元素 2 递归折半查找 3 类设计 从上面的算法分析可以看到 本设计面临的计算问题的关键是矩阵运算 可以定义一个矩阵类 Matrix 作为基类 然后由矩阵类派生出线性方程组类 Linequ 矩阵类 Matrix 只处理 n n 类型的方阵 方阵用一个一维数组来存放 矩阵类 Matrix 的数据成员包括数组的首地址和 n 矩阵类 Matrix 的功能有设置 矩阵的值 SetMatrix 和显示矩阵 PrintM 等 从问题的需要来看 线性方程组类 Linequ 的数据除了由矩阵类 Matrix 继承 过来用于存放系数矩阵 A 的成员外 还应该包括存放解向量 x 和方程右端向量 b 的数组首地址 线性方程组类 Linequ 的主要操作有设置 SetLinequ 显示 PrintL 求解 Solve 及输出方程的解 showX 可以通过定义线性 方程组类 Linequ 的新增成员函数来实现这些针对方程组求解的功能 矩阵类 Matrix 和线性方程组类 Linequ 的组成及相互关系如图 1 所示 图 1 Matrix 类和 Linequ 类的派生关系的 UML 图形表示 在线性方程组的求解过程中 在线性方程组类 Linequ 的成员函数 Solve 中 需要访问基类矩阵类 Matrix 的数据成员 利用公有继承方式派生 同时将 M a t r i x i n d e x i n t M a t r i x d o u b l e M a t r i x d i m s i n t 2 M a t r i x S e t M a t r i x r m a t r d o u b l e v o i d P r i n t M v o i d l i n e q u s u m s d o u b l e s o l u d o u b l e L i n e q u d i m s i n t 2 L i n e q u S e t L i n e q u a d o u b l e b d o u b l e v o i d P r i n t L v o i d S o l v e i n t S h o e X v o i d Matrix 类中的数据成员的访问控制设置为保护类型 这样 经过公有派生之后 基类的保护成员在派生类中依然是保护成员 可以被派生类的成员函数访问 4 详细设计 整个程序分为三个独立的文档 Linequ h 文件中包括矩阵类 Matrix 和线性 方程组类 Linequ 的声明 Linequ cpp 文件中包括这两个类的成员函数实现文件 main cpp 文件包括程序的主函数 主函数中定义了一个类 Linequ 的对象 通过 这个对象求解一个四元线性方程组 4 1 类的接口设计 Linequ h 文件 实现类的声明 include include using namespace std class Matrix 基类 Matrix 声明 public 外部接口 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 显示方程 int Solve 全选主元高斯消去法求解方程 void ShowX 显示方程的解 private 私有数据 double sums 方程右端项 double solu 方程的解 经过公有派生 Linequ 类获得了除构造函数 析构函数之外的 Matrix 类的 全部成员 由于基类的成员是公有和保护类型 因此在派生类中的成员函数中 基类继承来的成员全部可以访问 而对于建立 Linequ 类对象的外部模块来讲 基类的保护成员是无法访问的 通过保护访问类型和公有的继承方式 实现了 基类 Matrix 的数据的有效共享和可靠保护 在程序中 方程的系数矩阵 解以 及右端项全部采用了动态内存分配技术 这些工作都是在基类 派生类的构造 函数中完成 它们的清理工作在析构函数中完成 4 2 类的实现 Linequ cpp 文件 类实现 include linequ h 包含类的声明头文件 Matrix 类的实现 void Matrix SetMatrix double rmatr 设置矩阵 for int i 0 i index index i MatrixA i rmatr i 矩阵成员赋初值 Matrix Matrix int dims 矩阵 Matrix 类的构造函数 index dims 矩阵行数赋值 MatrixA new double index index 动态内存分配 Matrix Matrix 矩阵 Matrix 类的析构函数 delete MatrixA 内存释放 void Matrix PrintM 显示矩阵元素 cout The Matrix is endl for int i 0 i index i for int j 0 j index j cout MatrixA i index j cout endl 派生类 Linequ 的实现 Linequ Linequ int dims Matrix dims 派生类 Linequ 的构造函数 使用参数调用基类构造函数 sums new double dims 动态内存分配 solu new double dims Linequ Linequ 派生类 Linequ 的析构函数 delete sums 释放内存 delete solu void Linequ SetLinequ double a double b 设置线性方程组 SetMatrix a 调用基类函数 for int i 0 i index i sums i b i void Linequ PrintL 显示线性方程组 cout The line equation is endl for int i 0 i index i for int j 0 j index j cout MatrixA i index j cout sums i endl void Linequ ShowX 输出方程组的解 cout The result is endl for int i 0 i index i cout X i solu i endl int Linequ Solve 全选主元高斯法求解方程 int js l k i j is p q double d t double MatrixB 声明局部矩阵 MatrixB MatrixB new double index index 将矩阵 MatrixA 赋值给 MatrixB for i 0 i index index i MatrixB i MatrixA i js new int index 分配动态内存 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 js k j is i if d 1 0 1 0 主元素为零 l 0 else 主元素交换 if js k k for i 0 i index 1 i p i index k q i index js k t MatrixB p MatrixB p MatrixB q MatrixB q t if is k for j k j index 1 j p k index j q is index j t MatrixB p MatrixB p MatrixB q MatrixB q t t sums k sums k sums is sums is t if l 0 若主元素为零 求解失败 delete js cout fail endl return 0 d MatrixB k index k 归一化计算 for j k 1 j index 1 j p k index j MatrixB p MatrixB p d sums k sums k d for i k 1 i index 1 i 消去计算 for j k 1 j index 1 j p index i j MatrixB p MatrixB p MatrixB i index k MatrixB k index j sums i sums i MatrixB i index k sums k d MatrixB index 1 index index 1 if fabs d 1 0 1 0 delete js cout fail 0 i t 0 0 for j i 1 j 0 k if js k k t solu k solu k solu js k solu js k t delete js return 1 在类的成员函数实现过程中 派生类的构造函数使用参数调用了基类的构 造函数 为矩阵动态分配了内存空间 而派生类的析构函数同样也调用了基类 的析构函数 只是整个调用过程中完全是由系统内部完成 基类的保护数据成 员 经过公有派生之后 在派生类中是以保护成员的身份出现的 派生类的成 员函数可以自由地进行访问 全选主元高斯消去法求解函数返回值为整数 正常完成之后 返回值为 1 非正常结束后 返回值为 0 根据函数的返回值 就可以判断求解过程的完 成情况 4 3 主函数设计 main cpp 主函数 include linequ h int main 主函数 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 b 4 1 8471 1 7471 1 6471 1 5471 方程右端项 Linequ equ1 4 定义一个四元方程组对象 equ1 SetLinequ a b 设置方程组 equ1 PrintL 输出方程组 if equ1 Solve 求解方程组 equ1 ShowX 输出方程组的解 else cout Fail endl 求解失败 return 1 在程序的主函数部分 选择了一个四元方程组作为一个实际例子来验证算 法 方程组的系数及右端项数据都使用一维数组来存储 首先定义一个四元方 程组对象 equ1 在定义过程中调用派生类的构造函数 通过派生类的构造函数 又调用了基类的构造函数 对进一步求解动态分配了内存 接着给方程组的系 数和右端项赋初值 把我们选定的方程组输入到新定义的方程组对象 equ1 中 对象成员函数 PrintL Solve 和 ShowX 分别完成了输出方程组 求解方程组和 输出求解结果的任务 5 DOS 界面程序运行结果及分析 5 1 程序运行结果 程序运行结果如图 2 所示 图 2 程序运行结果 从图 2 中可以看出 程序能够实现全选主元高斯消去法对于线性方程组的 求解 但是 对于求解结果的正确性问题却无法获知 为了能够验证求解结果 的正确性 考虑将求解结果 x 带入原方程 Ax b 中 如果满足原方程 即说明 求解结果是正确的 否则 说明求解存在问题 需对程序进行进一步调试分析 为此 考虑在 Linequ 类中增加测试函数 Test 用以验证求解结果的正确性 void Linequ test 求解结果验证函数 double b2 b2 new double index for int i 0 i index i 将解 solu 带入原方程求出新的右端项 b2 b2 i 0 for int j 0 j index j b2 i b2 i MatrixA i index j solu j for i 0 i index i 输出新的右端项 cout b2 i cout endl 在主函数 main 中增加语句 equ1 test 验证求解结果 经过验证的程序运行结果如图 3 所示 图 3 程序运行结果的验证 从图 3 中可以看出 方程组求解验证的右端项结果与原右端项结果完全一 致 这说明了方程组求解的正确性 5 2 运行结果分析 整个程序中的矩阵存储采用的是一维数组和动态内存分配方式 基类是专门处理矩阵的类 公有派生类 Linequ 是针对线性方程组而设计的 除了继承基类的基本特征之外 结合问题的实际需要 增加了很多线性方程组 所特有的成员 使基类 Matrix 进一步具体化 特殊化 达到对问题的有效描述 和处理 程序的访问控制也是根据问题的需要而设计的 基类的数据成员的存储 维护着矩阵数据 这正是派生类方程组的系数矩阵 使派生类解方程成员函数 必须访问的 利用保护成员特征 将基类数据成员的访问控制属性设置为保护 型 在公有派生类 Linequ 中就可以访问到基类继承下来的保护成员 而对于类 外的其余模块 这些数据无法访问 这样 就在数据的共享与隐藏之间寻找到 一个比较恰当的结合点 在派生过程中 基类的构造函数和析构函数无法继承下来 因此在派生类 中需要添加构造函数 析构函数来完成派生类的初始化和最后清理工作 派生 类的构造函数通过调用基类的构造函数来对基类数据进行初始化 本设计中 派生类 Linequ 的构造函数调用了基类 Matrix 的构造函数并传递必须的初始化参 数 派生类的析构函数调用基类的构造函数 共同完成清理任务 6 基于 MFC 的图形界面程序开发 MFC 的图形界面程序设计可在上述类设计的基础上进行改造 MFC 的图 形界面程序与 DOS 界面程序的主要不同点是 MFC 图形界面程序与 DOS 界面 程序的输入输出方式不同 DOS 界面程序采用字符交互式实现数据输入输出 主要通过 cin cout 等 I O 流实现 而 MFC 的图形程序界面采用标准 Windows 窗口和控件实现输入输出 因此必须在 MFC 类的框架下加入上面所设计的矩阵 和方程组类 并通过图形界面的输入输出改造来完成 6 1 基于 MFC 的图形界面程序设计 1 界面设计 首先在 VC 中建立 MFC AppWizard exe 工程 名称为 GuassLineGUI 并在向导的 Step1 中选择 Dialog based 即建立基于对话框的应用程序 如下图 4 5 所示 图 4 建立 MFC AppWizard exe 工程 图 5 建立基于对话框的应用程序 将对话框资源中的默认对话框利用工具箱改造成如下界面 如图 6 所示 图 6 方程组求解程序界面设计 图 6 所示的界面中包含了 3 个 Static Text 控件 3 个 Button 控件 和 24 个 Edit Box 控件 控件的基本信息列表如下表 1 所示 表 1 控件基本信息 控件类别 控件 ID 控件 Caption 说明 系数矩阵 A 方程组右端项 bStatic Text IDC STATIC 解 X IDC BUTTON Read 读入数据 IDC BUTTON CALC 计算求解Botton IDC BUTTON Exit 退出 IDC EDIT A00 IDC EDIT A33 矩阵 A 的 16 个元 素 IDC EDIT b0 IDC EDIT b3 向量 b 的 4 个元素 Edit Box IDC EDIT X0 IDC EDIT X3 解 X 的 4 个元素 2 代码设计 为了能够将对话框界面上的控件能够与代码联系起来 需要为 24 个 Edit Box 控件建立 Member Variables 按 Ctrl w 键进入 MFC ClassWizard 界面 选 择 Member Variables 选项卡 可显示成员变量设置界面 如图 7 所示 图 7 成员变量设置界面 通过该界面设置与 24 个 Edit Box 控件对应的成员变量 具体如表 2 所示 表 2 控件基本信息 控件 ID 成员变量类型 成员变量名称 IDC EDIT A00 IDC EDIT A33 double m A00 m A33 IDC EDIT b0 IDC EDIT b3 double m b0 m b3 IDC EDIT X0 IDC EDIT X3 double m X0 m X3 下面是编写代码的重要阶段 可以借鉴在设计基于 DOS 界面的控制台应用 程序的代码 并将其作必要的改写 具体改写的步骤与内容如下 将 Linequ h 文件和 Linequ cpp 文件合并成一个文件 重新命名为 Linequ h 并将其加入 MFC 工程 修改 Linequ h 文件具体包括 将显示矩阵 PrintM 函数和显示方程 PrintL 函数注释掉 因为 在图形界面的程序上已经不需要连个函数承担输出功能了 将输出方程组的解 ShowX 函数加入参数 double x 变成 ShowX double x 以实现将所求的解输出至参数 x 中 并最终完成 在对话框界面上的显示 将全选主元高斯法求解函数 Solve 中的两处 cout 语句去掉 因为 不需要也不能够使用 cout 流实现输出 在对话框类的实现文件 GuassLineGUIDlg 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 b 4 1 8471 1 7471 1 6471 1 5471 方程右端项 double X 存放方程组的解 编写读入数据按钮的消息处理函数 实现将矩阵和右端项的数据刷新到 界面上 具体代码如下 void CGuassLineGUIDlg OnBUTTONRead TODO Add your control notification handler code here m A00 a 0 m A01 a 1 m A02 a 2 m A03 a 3 m A10 a 5 m A11 a 6 m A12 a 7 m A13 a 8 m A20 a 9 m A21 a 10 m A22 a 11 m A23 a 12 m A30 a 13 m A31 a 14 m A32 a 15 m A33 a 16 m b0 b 0 m b1 b 1 m b2 b 2 m b3 b 3 UpdateData FALSE 编写计算求解按钮的消息处理函数 实现将方程求解 具体代码如下 void CGuassLineGUIDlg OnButtonCalc TODO Add your control notification handler code here Linequ equ1 4 定义一个四元方程组对象 equ1 SetLinequ a b 设置方程组 X new double 4 if equ1 Solve 求解方程组 equ1 ShowX X 输出方程组的解 m X0 X 0 m X1 X 1 m X2 X 2 m X3 X 3 UpdateData FALSE else MessageBox 求解失败 求解失败 退出按钮比较简单 代码如下 void CGuassLineGUIDlg OnBUTTONExit TODO Add your control notification handler code here OnOK 6 2 程序测试 运行程序后 首先出现的界面如图 8 所示 图 8 程序初始运行界面 单击读入数据按钮后 可将系数矩阵 A 和方程组右端项 b 的数据在界面上 显示出来 如图 9 所示 图 9 读入数据后的界面 单击计算求解按钮 实现求解并将解显示出来 如图 10 所示 图 10 求解方程组后的界面 单击退出按钮后 程序能够正常实现退出 6 3 MFC 程序编写总结 MFC 程序与 DOS 界面程序编写的最大不同是程序员需要将编程精力放在 图形界面设计 图形界面输入输出以及界面元素和代码对应转换等问题上 而 这些问题在 DOS 界面程序中是不存在的 因此 初学 MFC 的编程者会对此感 到困难 然而 当你编写出一个基于 Windows 界面的程序时 所获得的满足程 度远远大于简单的 DOS 界面程序 况且基于 Windows 的图形界面的程序设计 已成为主流 作为程序员而言 是非学会不可的 本次课程设计作为编写 Windows 程序的初步尝试 能够实现程序的主要功 能 可以说是取得了成功 然而好的程序绝不仅仅是只有功能性这一个指标 本此编写的 MFC 程序虽然能实现所需功能 但从面向对象程序设计理念和图形 界面设计要求来说 尚存在不足 主要包括以下几个方面 1 使用全局变量存储矩阵系数 方程组右端向量和解向量本身有悖面向 对象程序设计理念 需要将其改进 利用局部变量和其它方式实现存储 作者 认为最理想的方式是使用文件 2 将类的定义与实现放在同一个头文件 Linequ h 中也违背了面向对象程 序设计理念 需要将二者分开成定义文件和实现文件 3 图 10 所示的界面中对解的显示没有格式化 导致界面看起来不够规 范 需要对解的输出进行小数点固定位数显示 7 参考文献 1 徐士良 C 常用算法程序集 北京 清华大学出版社 1995 2 郑莉 董渊 张瑞丰 C 语言程序设计 第 3 版 北京 清华大学出版社 2007 3 钱能 C 程序设计教程 第二版 北京 清华大学出版社 2007 4 陈志泊 王春玲 面向对象的程序设计语言 C 北京 人民邮电出版社 2002 5 李庆扬 王能超 易大义 数值分析 湖北 华中理工大学出版社 1986
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 建筑环境 > 建筑工程


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!