2023年通信工程专业面向对象课程设计要求与指导_第1页
2023年通信工程专业面向对象课程设计要求与指导_第2页
2023年通信工程专业面向对象课程设计要求与指导_第3页
2023年通信工程专业面向对象课程设计要求与指导_第4页
2023年通信工程专业面向对象课程设计要求与指导_第5页
已阅读5页,还剩38页未读 继续免费阅读

下载本文档

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

文档简介

2023级《面向对象课程设计》规定与指导

专业:通信工程

指导教师:任世卿,刘洋,马玉峰,李晓静

一、课程设计的目的

面向对象课程设计是通信工程专业非常重要的实践性环节之一,是学完面向对象程序设

计课程后的一次全面的综合练习。本课程设计重要在于巩固学生对面向对象程序设计的基础

理论的理解,掌握面向对象程序设计开发的基本方法,进一步提高学生综合运用所学知识的

能力。

二、课程设计的规定及内容

(一)课程设计的基本规定

以MicrosoftVisua1C++6.0作为集成开发环境,完毕面向对象课程设计。规

定每人完毕一个题目,题目由指导教师指派,学生与题目之间一一相应(即两个学生的题目不

能反复),学生进行程序分析、设计、编程与调试、功能测试,并最终完毕课程设计报告。其

中每个题目必须采用类与对象进行编程,每个题目的程序必须用两种工程实现,一种是Win3

2ConsoleApplication,输入输出采用传统DOS的字符式交互界面;另一种是MFC

AppWizard(exe),输入输出采用基于Windows的图形式交互界面。

(二)各题目具体规定

1.分数类的设计与实现

建立用于完毕分数形式运算的类Rationa1Number„编写一个测试该类的程序。用

整数变量表达类的私有数据(即分子和分母)。给类提供一个可以对所声明的对象初始化的构

造函数。为了可以在不提供初始化值的情况下也能对对象初始化,构造函数中应当包含默认

的值。构造函数还应当以最简分数的形式存储数据,即2/4应当在对象中存储成分子为1、

分母为2的形式。公有成员函数应当有以下功能:

(1)两个有理数相加,以最简形式保存结果;

(2)两个有理数相减,以最简形式保存结果;

(3)两个有理数相乘,以最简形式保存结果;

(4)两个有理数相除,以最简形式保存结果;

(5)以a/b的形式输出有理数(a是分子,b是分母);

(6)以浮点形式输出有理数。

2.一维数组类模板的设计与实现

建立一维数组数据结构的模板类,使一维数组中的数据元素可以是char,int,floa

t等多种数据类型,类中的成员函数重要涉及:

(1)排序函数,可以对数组元素进行升序排列;

(2)查找函数,可以在输入待查元素后,输出其在数组中的下标;

(3)构造函数,初始化输入数组元素,这里规定数组元素的个数n是一个变量;

(4)析构函数,释放数组元素所占用的堆内存;

(5)Set函数,可认为指定的数组元素赋值;

(6)Get函数,可以读取指定数组元素的值;

(7)Print函数,可以输出数组元素的值。

(8)编写一个测试该模板类的程序。

3.向量类的设计与实现

编写一个实现n维向量各种操作的类,功能涉及:

(1)构造函数实现n维向量的初始化构造,这里n可变;

(2)析构函数实现向量动态内存的释放;

(3)拷贝构造函数实现向量的拷贝构造:

(4)重载赋值运算符'=',实现两个向量之间的赋值;

(5)编写成员函数求两个向量的内积;

(6)编写成员函数求两个向量的外积;

(7)编写成员函数求两个向量的和;

(8)编写成员函数求两个向量的差;

(9)编写成员函数判断两个向量之间的线性相关性。

(10)编写一个主函数测试多项式类的上述功能。

4.多项式类的设计与实现

开发多项式类Polynomial,多项式的每一项用链表的结点表达,每项包含一个系数

和一个指数。例如:2x"的指数为4,系数为2。请开发一个完整的Polynomial类,涉

及构造函数、析构函数以及"get”函数(读取值)和“set”函数(设立值)。该类还要提供

以下重载的运算符:

(1)重载加法运算符+,将两个多项式相加。

(2)重载加法运算符一,将两个多项式相减。

(3)重载赋值运算符=,将一个多项式赋给此外一个多项式。

(4)重载加法运算符*,将两个多项式相乘。

(5)编写一个主函数测试多项式类的上述功能。

5.基于成员函数的方阵类设计与实现

设计一个可以实现nXn矩阵操作的类,这里的n可变,重要功能涉及:

(1)使用构造函数完毕方阵的初始化赋值;

(2)使用析构函数完毕矩阵动态内存的释放;

(3)使用函数实现两个矩阵的和;

(4)使用函数实现两个矩阵的差;

(5)使用函数实现两个矩阵的积;

(6)使用函数实现矩阵的转置;

(7)使用函数求矩阵中的最大值;

(8)使用函数求矩阵中的最小值。

(9)编写一个主函数测试上述功能。

6.基于运算符重载的方阵类设计与实现

设计一个可以实现nXn矩阵操作的类,这里的n可变,重要功能涉及:

(1)使用构造函数完毕方阵的初始化赋值;

(2)使用析构函数完毕矩阵动态内存的释放:

(3)重载加法运算符+,实现两个矩阵的和;

(4)重载加法运算符实现两个矩阵的差;

(5)重载加法运算符*,实现两个矩阵的积;

(6)重载加法运算符=,实现两个矩阵之间的赋值:

(7)使用拷贝构造函数完毕方阵的拷贝构造;

(8)重载加法运算符〈<,实现矩阵按照行列的格式输出;

(9)编写一个主函数测试上述功能。

7.复数类的设计与实现

设计一个复数类,复数类的数据成员是rea1和imag,它们的数据类型是doub1e,分

别表达复数的实部和虚部,规定如下:

(1)编写一个带有缺省参数的构造函数,默认值为(0,0),实现一个复数的构造。

(2)编写一个拷贝构造函数,实现一个复数的拷贝构造。

(3)编写一个析构函数,在函数中输出(real,imag)被析构,例如:假如复数的实部

为1,虚部为2,则被析构时程序输出:“(1,2)被析构”。

(4)重载运算符“+”为复数类的成员函数,其功能是返回两个复数的相加的结果。

(5)重载运算符“一”为复数类的成员函数,其功能是返回两个复数的相减的结果。

(6)重载运算符“*”为复数类的友元函数,其功能是返回两个复数的相乘的结果。

(7)重载运算符“/”为复数类的友元函数,其功能是返回两个复数的相除的结果。

(8)重载单目运算符“一”为复数类的友元函数,其功能是返回当前复数的相反数。

(9)重载运算符“>>”为复数类的友元函数,其功能是按照以格式(real,imag)

(10)输入复数。例如:假如复数的实部为1,虚部为2,则输入的格式是“(1,2)”。

(11)重载运算符“<<”为复数类的友元函数,其功能是按照以格式(real,imag)

(12)输出复数。例如:假如复数的实部为1,虚部为2,则输出的结果是“(1,2)”。

(13)以上函数在类的内部写出函数原型,在类的外部写出函数实现代码,最后编写一

个主函数main测试以上的函数功能。

8.单链表类的设计与实现

编写一个实现学生信息单链表各种操作的类,学生信息涉及学号、姓名和成绩,类实现

以下功能:

(1)初始化单链表为空表;

(2)实现单链表的插入操作的成员函数;

(3)实现单链表的删除操作的成员函数;

(4)实现单链表的查找操作的成员函数(给定学号,查找其学号、姓名和成绩);

(5)实现求单链表长度的成员函数;

(6)实现建立单链表的成员函数,单链表节点的个数不拟定。

(7)编写一个主函数测试上述功能。

9.大整数类的设计与实现

计算机中表达整数的位数是有限的,设计并实现一个可以进行任意长度整数准确计算的

类,完毕以下功能:

(1)用构造函数实现大整数的构造。

(2)重载“+”运算符,实现两个大整数的相加运算;

(3)重载运算符,实现两个大整数的相减运算;

(4)重载“*”运算符,实现两个大整数的相乘运算;

(5)重载“<<”运算符,实现大整数的输出。

提醒:长整数用一维字符型数组来存储,数组的每一个元素顺序存储长整数的一位数字。

设有k位长整数叫用数组a□存储:

<>m=a[k]*10"(k-l)+aEk—1]*10(k-2)+...+a[2]*10*l+a[l]*10*0

并用a[0]存储长整数m的位数,即a[0]=k。

10.小型人员信息管理系统的设计与实现

某小型公司重要有四类人员:经理、兼职技术人员、销售经理和兼职推销员。现在,需

要存储这些人员的姓名、编号、级别、当月薪水,计算月薪总额并显示所有信息。

人员编号基数为1000,每输入一个人员信息编号顺序加1。

程序要有对所有人员提高级别的功能。本例中为简朴起见,所有人员的初始级别均为1

级,然后进行升级,经理升为4级,兼职技术人员和销售经理升为3级,推销员认为1级。

月薪计算办法是:经理拿固定月薪8000元;兼职技术人员按每小时100元领取月薪;

兼职推销员的月薪按该推销员当月销售额的4%提成;销售经理即拿固定月薪也领取销售提

成,固定月薪为5000元,销售提成为所管辖部门当月销售总额的千分之五。

规定为每一类人员单独建立文献,并在每个文献中手工录入一些人员基本信息,并根据

这些基本信息计算职工的月薪,并将计算结果保存入相应的磁盘文献中。规定编写程序实现

上述功能,并且可以通过实例演示上述功能。

11.大学教师工资的计算与存储

某大学的教师的职称等级决定其工资等级,教师共有四种职称等级:助教,讲师,副专

家,专家,其月薪分别为:助教900元/月,讲师1000元/月,副专家1300元/月,专家1600

元/月。编写一个计算教师工资的程序,规定如下:

(1)建立一个抽象基类Teacher,其数据成员有:教师姓名name,教师职称position,

教师工资Salary;成员函数有:纯虚函数Ca1cSalary()计算教师工资,纯虚函数Show()

输出教师的姓名、职称和工资。

(2)分别从抽象基类Teacher中派生出四个具体类Assistant,Lecture,Asso

ciateProfessor,Professor,分别表达助教,讲师,副专家,专家。在每一个类中实

现三个成员函数,构造函数为教师初始化姓名和职称;CalcSalary()函数计算教师工

资;Show()输出教师的姓名、类别和工资,其中输出格式为:

姓名:name,职称:position,工资:Salary元

(3)教师的姓名和职称信息包含在磁盘文献teacher.txt中,规定建立teache

r.txt文本文献,并输入如下信息:

王刚助教

李铭讲师,

张莉副专家

赵蒙专家

程序从Teacher.txt文献中读取上述信息,作为工资计算依据。

(4)编写一个主函数main测试以上各类,规定用一个基类的指针分别指向派生类对象

分别计算每一个人的工资,并将输出结果保存到Teacher.txt文献中。例如输出如下结果:

王刚助教900

李铭讲师1000

张莉副专家1300

赵蒙专家1600

12.小型教师与干部管理信息系统的设计与实现

分别定义Teacher(教师)类和Cadre(干部)类,采用多重继承方式由这两个类派

生出新类Teacher_Cadre(教师兼干部)。规定:

(1)在两个基类中都包含姓名、年龄、性别、地址、电话等数据成员。

(2)在Teacher类中还包含数据成员tit1e(职称),在Cadre类中还包含数据

成员post(职务),在Techear_Cadre类中还包含数据成员wages(工

资)。

(3)对两个基类中的姓名、年龄、性别、地址、电话等数据成员用相同的名字,在引

用这些数据成员时,指定作用域。

(4)在类体中声明成员函数,在类外定义成员函数。

(5)在派生类Teacher_Cadre的成员函数show中调用Teacher类中的disp

1ay函数,输出姓名、年龄、性别、职称、地址、电话,然后再用cout语句输

出职务与工资。

(6)人员的基本信息分别存储在磁盘文献Teacher.txt,Cadre.txt和Teac

her_Cadre.txt文献中,Teacher.txt的格式是:(姓名、年龄、性别、地址、

电话、职称),Cadre.txt的格式是:(姓名、年龄、性别、地址、电话、职务),

TeachejCadre.txt的格式是:(姓名、年龄、性别、地址、电话、职称、

职务、工资),规定在操作系统中建立上述文献,并按照上述格式手工录入几条

记录,程序一方面从文献中读取相应数据,然后完毕上述功能。

13.图形面积的计算与存储

写一个程序,定义抽象基类Shape,由它派生出5个派生类:Circle(圆形)、Squre

(正方形)、Rectangle(矩形)、Trapezoid(三角形)。用虚函数分别计算几种图形面积,

并求它们的和。规定用基类指针数组,使它的每个元素指向一个派生类对象。规定将计算的

各种图形面积以及它们和的结果存到磁盘文献ShapeArea.txt中。

14.约瑟夫环问题的求解与仿真

约瑟夫环(Joseph)问题的一种描述是:编号为1,2,…,n个人按顺时针方向围坐一

圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数的上限值m,从第一个人

开始按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为

新的m值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直到所有人所有

出列为止。试通过类的设计求解约瑟夫环问题的出列顺序。具体的规定和说明如下:

(1)运用单向循环链表存储结构模拟此过程,按照出列的顺序输出个人的编号。

(2)m的初值为20;n=7,7个人的密码依次为:3,1,7,2,4,8,4,一方面m的值为6

(对的的出列顺序应为:6,1,4,7,2,3,5)。

(3)程序运营后,一方面规定用户指定初始报数的上限值,然后读取个人的密码。可设n

<=30,此题所用的循环链表中不需要“头结点”,请注意空表和非空表的界线。

(4)将上述功能改为在顺序结构上实现。

15.集合类的设计与实现

通过类与对象的设计,编制一个能演示执行集合的并、交和差运算的程序,规定如下:

(1)集合的元素限定为小写字母字符['az']。

(2)演示程序以用户和计算机的对话方式执行。

(3)以有序链表表达集合。

(4)可进一步实现集合的元素鉴定和子集鉴定运算。

16.基于插入排序方法的类模板设计与实现

建立一维数组数据结构的模板类,使一维数组中的数据元素可以是char,int,fl

oat等多种数据类型,并对数组元素实现插入类排序。重要完毕如下功能:

(1)实现数组数据的输入和输出;

(2)实现直接插入排序功能;

(3)实现2-路插入排序功能;

(4)实现希尔排序功能;

(5)将每种排序功能作为类的成员函数实现,编写主函数测试上述排序功能。

17.基于互换排序方法的类模板设计与实现

建立一维数组数据结构的模板类,使一维数组中的数据元素可以是char,int,float

等多种数据类型,并对数组元素实现互换类排序。重要完毕如下功能:

(1)实现数组数据的输入和输出;

(2)实现单向起泡排序功能;

(3)实现双向起泡排序功能;

(4)实现快速排序功能;

(5)将每种排序功能作为类的成员函数实现,编写主函数测试上述排序功能。

18.基于选择排序方法的类模板设计与实现

建立一维数组数据结构的模板类,使一维数组中的数据元素可以是char,int,fl

oat等多种数据类型,并对数组元素实现选择类排序。重要完毕如下功能:

(1)实现数组数据的输入和输出:

(2)实现简朴选择排序功能;

(3)实现树形选择排序功能;

(4)实现堆排序功能;

(5)将每种排序功能作为类的成员函数实现,编写主函数测试上述排序功能。

19.静态查找类模板的设计与实现

建立一维数组数据结构的模板类,使一维数组中的数据元素可以是char,int,

float等多种数据类型,并对数组元素进行静态查找。重要完毕如下功能:

(1)实现数组数据的输入和输出;

(2)对数组进行顺序查找;

(3)对有序数组进行折半查找(递归算法);

(4)对有序数组进行折半查找(非递归算法);

(5)将每种查找功能作为类的成员函数实现,编写主函数测试上述查找功能。

20.动态查找类模板的设计与实现

实现以二叉排序树为代表的动态查找表类模板,数据元素可以是char,int,f1oat

等多种数据类型,涉及以下功能:

(1)采用二叉链表存储结构实现二叉排序树的存储;

(2)实现二叉排序树的建树;

(3)实现二叉排序树结点的插入;

(4)实现二叉排序树结点的删除;

(5)实现二叉排序树结点的查找;

(6)将上述功能作为类的成员函数实现,编写主函数测试上述查找功能。

21.基于开放地址法的哈希表类模板设计与实现

实现哈希表类模板,数据元素可以是char,int,fl。at等多种数据类型,涉及以下

功能:

(1)实现哈希表的建立,散列函数采用除留余数法;

(2)使用开放地址法解决冲突;

(3)实现哈希表元素的插入;

(4)实现哈希表元素的删除;

(5)实现哈希表的查找;

(6)将上述功能作为类的成员函数实现,编写主函数测试上述查找功能。

22.基于链地址法的哈希表类模板设计与实现

实现哈希表类模板,数据元素可以是char,int,float等多种数据类型,涉及以下

功能:

(1)实现哈希表的建立,散列函数采用除留余数法;

(2)使用链地址法解决冲突;

(3)实现哈希表元素的插入;

(4)实现哈希表元素的删除;

(5)实现哈希表的查找;

(6)将上述功能作为类的成员函数实现,编写主函数测试上述查找功能。

23.赫夫曼编码的设计与实现

进行赫夫曼编码类的设计并实现,涉及以下功能:

(1)设计类的数据成员和成员函数,实现赫夫曼树的存储;

(2)根据给定的通信字符出现的概率,实现赫夫曼树的建立;

(3)遍历赫夫曼树,求赫夫曼编码;

(4)给出一段字符串,进行赫夫曼编码;

(5)将上述功能作为类的成员函数实现,编写主函数测试上述功能。

24.二叉树类模板的设计与实现

进行二叉树类模板的设计并实现,数据元素可以是char,int,float等多种数据类

型,涉及以下功能:

(1)采用顺序存储结构或链式存储结构实现二叉树的存储;

(2)实现二叉树的建树;

(3)实现二叉树的前序、中序、后序遍历;

(4)可以求解二叉树的结点总数和叶子结点总数;

(5)可以求解二叉树的高度;

(6)将上述功能作为类的成员函数实现,编写主函数测试上述功能。

25.队列类模板的设计与实现

进行队列类模板的设计并实现,队列采用循环队列实现,数据元素可以是char,int,

f1oat等多种数据类型,涉及以下功能:

(1)实现初始化队列操作,建立一个空队列;

(2)实现清空队列操作;

(3)实现判断队列是否为空的操作;

(4)实现求队列长度的操作;

(5)实现返回队首元素的操作;

(6)实现入队操作;

(7)实现出队操作;

(8)实现队列的遍历操作,输出队列的每个元素。

(9)将上述功能作为类的成员函数实现,编写主函数测试上述功能。

26.栈类模板的设计与实现

进行栈类模板的设计并实现,栈采用链式存储结构,数据元素可以是char,int,fl

oat等多种数据类型,涉及以下功能:

(1)实现初始化栈操作,建立一个空栈;

(2)实现清空栈操作;

(3)实现判断栈是否为空的操作;

(4)实现求栈长度的操作;

(5)实现返回栈顶元素的操作;

(6)实现入栈操作;

(7)实现出栈操作;

(8)实现栈的遍历操作,输出栈的每个元素。

(9)将上述功能作为类的成员函数实现,编写主函数测试上述功能。

27.表达式求值的设计与实现

表达式求值是程序设计语言编译中的一个最基本问题,规定进行类的设计与实现,采用

算符优先法实现表达式求值。具体规定如下:

(1)用顺序栈作为表达式求值过程中运算符栈和操作数栈的实现;

(2)用二维数组存储算符间的优先关系;

(3)采用算符优先法实现表达式求值;

(4)将上述功能作为类的成员函数实现,编写主函数测试上述功能。

28.基于Dijkstra算法的最短途径问题求解

进行类的设计与实现,解决最短途径问题。具体规定如下:

(1)采用图的邻接矩阵或邻接表实现最短途径问题中图的存储;

(2)采用Dijkstra算法求从某个源点到其余各顶点的最短途径;

(3)将上述功能作为类的成员函数实现,编写主函数测试上述功能。

29.基于Floyd算法的最短途径问题求解

进行类的设计与实现,解决最短途径问题。具体规定如下:

(1)采用图的邻接矩阵或邻接表实现最短途径问题中图的存储;

(2)采用F1。yd算法求每一对顶点的最短途径;

(3)将上述功能作为类的成员函数实现,编写主函数测试上述功能。

30.基于DFS算法的图的遍历问题求解

进行类的设计与实现,解决图的遍历问题。具体规定如下:

(1)采用图的邻接矩阵或邻接表实现最短途径问题中图的存储;

(2)采用递归程序实现图的深度优先搜索(DFS);

(3)将上述功能作为类的成员函数实现,编写主函数测试上述功能。

31.基于BFS算法的图的遍历问题求解

进行类的设计与实现,解决图的遍历问题。具体规定如下:

(1)采用图的邻接矩阵或邻接表实现最短途径问题中图的存储;

(2)采用队列实现图的广度优先搜索(BFS);

(3)将上述功能作为类的成员函数实现,编写主函数测试上述功能。

32.基于Prim算法的最小生成树问题求解

进行类的设计与实现,解决无向连通图的最小生成树的遍历问题。具体规定如下:

(1)采用图的邻接矩阵或邻接表实现最短途径问题中图的存储:

(2)采用普里姆(Prim)算法实现最小生成树问题的求解;

(3)将上述功能作为类的成员函数实现,编写主函数测试上述功能。

33.字符串类的设计与实现

进行字符串类的设计,具体规定如下:

(1)使用堆分派存储表达实现字符串的存储;

(2)实现串赋值操作StrAssign(&T,chars);

(3)实现串比较操作StrCompare(S,T);

(4)实现求串长操作StrLength(S);

(5)实现串连接操作Concat(&T,S1,S2)

(6)实现求子串操作SubString(&Sub,S,pos,len)

(7)实现清空子串操作C1earString(&S);

(8)将上述功能作为类的成员函数实现,编写主函数测试上述功能。

三、课程设计时间安排

本课程设计在学完面向对象程序设计课程后进行,具体时间为第17~19周,共3周。

四、课程设计考核办法

(1)课程设计报告

不少于5000字,报告除了在封面中应有题目、班级、姓名、学号和课程设计日期以外,

其正文一般涉及需求分析、类与对象设计、算法设计、图形界面设计、调试问题分析、参考

文献等部分。课程设计报告字体格式采用宋体,小四,行距为最小值20磅,具体可参照后面

的课程设计报告范例。

(2)程序演示和验收答辩情况

在课程设计的后期,指导教师在实验室进行课程设计程序的验收与答辩,由学生演示编

制的程序,并回答教师提出的问题,教师检查学生程序的编写情况。

(3)课程设计的考勤与纪律遵守情况

五、课程设计报告范例

下面给出了一个课程设计报告范例,作为同学撰写课程设计报告的参考。

封皮

(按学校规定手工填写)

课程设计任务书

学院信息科学与工程学院专业通信工程

学生姓名XXX学号1003060XXX

设计题目基于全选主元高斯消去法的线性方程组求解

内容及规定:

很多自然科学和工程技术中的问题的解决最终都归结到线性方程组的求解,

高斯消去法是线性方程组解法中很经典的算法,由它改善、变形得到的全选主元

消去法,是一种效率很高、较为常用的线性方程组解法。

规定采用C++语言实现线性方程组的求解,具体规定如下:

(1)进行类的设计,实现线性方程组的存储与操作。

(2)方程组的求解采用全选主元高斯消去法。

(3)编写主函数测试程序的功能。

进度安排:

第17周:分析题目,查阅课题相关资料,进行类设计、算法设计;

第18周:程序的设计、调试与实现;

第19周:程序测试与分析,撰写课程设计报告,进行答辩验收。

指导教师(签字):学院院长(签字)

年月年月日

目录

1需求分析。错误!未定义书签。

2算法基本原理...........................错误!未定义书签。

3类设计.................................错误!未定义书签。

4具体设计。错误!未定义书签。

4.1类的接口设计。错误!未定义书签。

4.2类的实现.....................................错误!未定义书签。

4.3主函数设计。错误!未定义书签。

5DOS界面程序运营结果及分析..............错误!未定义书签。

5.1程序运营结果.................................错误!未定义书签。

5.2运营结果分析................................错误!未定义书签。

6基于MFC的图形界面程序开发.............错误!未定义书签。

6.1基于MFC的图形界面程序设计。错误!未定义书签。

6.2程序测试。错误!未定义书签。

6.3MFC程序编写总结,错误!未定义书签。

7参考文献..............................错误!未定义书签。

1需求分析

(1)很多自然科学和工程技术中的问题的解决最终都归结到线性方程组的求

解,高斯消去法是线性方程组解法中很经典的算法,由它改善、变形得到的全选

主元消去法,是一种效率很高、较为常用的线性方程组解法。

(2)线性方程组的一般形式为Ax=b,其中A是线性方程组的系数矩阵,x

是列向量,是方程组的解,b也是列向量,这里假定A是非奇异矩阵。

(3)程序测试数据来自徐士良先生编著的《C常用算法程序集》中,所选的

方程是:

0.2368X()+0.247+0.2568x2+1.2671%=L8471

0.1968%+0.207卜]+L2168%+0.227lx3=1.7471(1)

O.1581xo+1.1675玉+0.1768X2+0.1871X3=1.6471

1.1161xo+O.l245西+0.1397X2+0.1490x3=1.5471

2算法基本原理

设有n元线性方程组:

+为内+…+=%

+为玉+…=R⑵

%,0工0+明仔+…+an-\,n-\Xn-\=bn-\

将⑵写成矩阵形式Ax=6,其中,

〃00〃01•a0.nh

a\()a\\仇

A=,x=,b=⑶

aa

1,0n-\A,"n-\,n-\_A-i.A-i_

将系数矩阵A和向量b放在一起,形成增广矩阵B:

“0041aO,nbq

o/AI\"10a\.n仇

8=(4,。)=...

an-1,0an-\,\an-\.n-\2,-1

全选主元消去就在这个B矩阵上进行,整个过程分为两个环节:

第一步,消去过程。

对于k从。开始到n-2结束,进行以下三步:

(1)一方面,从系数矩阵A的第k行、k列开始的子矩阵中选取绝对值最大

的元素作为主元素,例如:

W国旬卜°

k<j<n⑸

然后互换B的第k行与第il行,第k行与第j1歹这样,这个子矩阵中的具

有最大绝对值的元素被互换到第k行、k列的位置。

(2)另一方面,进行归一化计算。计算方法为:

akj~akj!akk,j-k+\,k+2,---,n-\

为=%/%(6)

(3)最后,进行消去运算:

aj}=akj-aikakj,j,i=k+l,k+2,---,n

=bj-ajkbk,i-k+l,k+2,---,n-l(7)

第二步,回代过程。

;r-)1(8)

瓦=瓦一工时%,i=n-2,n-\,■■■,n()

j=M

在这里,只是列出简要地给出了全选主元高斯消去法的算法环节,具体推导及

具体过程可参考数值分析方面的有关资料。

3类设计

从上面的算法分析可以看到,本设计面临的计算问题的关键是矩阵运算。可

以定义一个矩阵类Matrix作为基类,然后由矩阵类派生出线性方程组类Lineq

Uo矩阵类Matrix只解决nXn类型的方阵,方阵用一个一维数组来存放,矩

阵类Matrix的数据成员涉及数组的首地址和n,矩阵类Matrix的功能有设

立矩阵的值SetMatrix()和显示矩阵PrintM()等。

从问题的需要来看,线性方程组类Linequ的数据除了由矩阵类Matrix继承

过来用于存放系数矩阵A的成员外,还应当涉及存放解向量x和方程右端向量b

的数组首地址。线性方程组类Linequ的重要操作有设立SetLinequ()、显示

PrintL()、求解So1ve()及输出方程的解showX()0可以通过定义

线性方程组类Linequ的新增成员函数来实现这些针对方程组求解的功能。

矩阵类Matrix和线性方程组类Linequ的组成及互相关系如图1所示。

Matrix

#index:int

#Matrix:double*

+Matrix(dims:int=2)

+“Matrix()

+SetMatrix(rmatr:double*):void

+PrintM0:void

linequ

-sums:double*

-solu:double*

+Linequ(dims:int=2)

+^Linequ0

+SetLinequ(a:double*,b:double*):void

+PrintLO:void

+Solve():int

+ShoeX():void

图1Matrix类和Linequ类的派生关系的UML图形表达

在线性方程组的求解过程中,在线性方程组类Linequ的成员函数SoIve中

需要访问基类矩阵类Matrix的数据成员,运用公有继承方式派生,同时将Ma

trix类中的数据成员的访问控制设立为保护类型。这样,通过公有派生之后,基类

的保护成员在派生类中仍然是保护成员,可以被派生类的成员函数访问。

4具体设计

整个程序分为三个独立的文档,Linequ.h文献中涉及矩阵类Matrix和

线性方程组类Linequ的声明,Linequ.cpp文献中涉及这两个类的成员函数实

现文献;main.cpp文献涉及程序的主函数,主函数中定义了一个类Linequ的

对象,通过这个对象求解一个四元线性方程组。

4.1类的接口设计

//Linequ.h文献,实现类的声明

#include<iostream>

#inc1ude<cmath>

usingnamespacestd;

classMatrix。//基类Matrix声明

(

public:外部接口

<>Matrix(intdims=2);//构造函数

o-Matrix();。//析构函数

voidSetMatrix(double*rmax);//矩阵赋初值

voidPrintM();//显示矩阵

protected:

intindex;。。//方阵的行数

»doub1e*MatrixA;//矩阵存放数组首地址

);

classLinequ:pubIicMatrix®//公有派生类Linequ声明

{

public:"。。。〃外部接口

»Linequ(intdims=2);〃构造函数

~Linequ();。//析构函数

»voidSetLinequ(double*a,double*b);<>//方程赋值

»voidPrintL();“。//显示方程

<>intSolve();。。〃全选主元高斯消去法求解方程

voidShowX()?〃显示方程的解

private:。“//私有数据

»doub1e*sums;»»//方程右端项

。doub1e*solu;方程的解

);

通过公有派生,Linequ类获得了除构造函数、析构函数之外的Matrix类的所

有成员,由于基类的成员是公有和保护类型,因此在派生类中的成员函数中,基

类继承来的成员所有可以访问,而对于建立Linequ类对象的外部模块来讲,基类

的保护成员是无法访问的。通过保护访问类型和公有的继承方式,实现了基类

Matrix的数据的有效共享和可靠保护。在程序中,方程的系数矩阵、解以及右端

项所有采用了动态内存分派技术,这些工作都是在基类、派生类的构造函数中完

毕,它们的清理工作在析构函数中完毕。

4.2类的实现

//Linequ.cpp文献,类实现

include"linequ.h"。。//包含类的声明头文献

//Matrix类的实现

voidMatrix::SetMatrix(doub1e*rmatr)//设立矩阵

(

for(inti=O;i<index*index;i++)

»MatrixA[i]=rmatrLi];。〃矩阵成员赋初值

)

Matrix::Matrix(intdims)”/矩阵Matrix类的构造函数

(

index=dims;。//矩阵行数赋值

<>MatrixA=newdoubleLindex*index];//动态内存分派

)

Matrix::~Matrix()«//矩阵Matrix类的析构函数

(

»de1ete[]MatrixA;«//内存释放

)

voidMatrix::PrintM()。//显示矩阵元素

»cout«"TheMatrixis:"«endl;

ofor(inti=0;i<index;i++)

(

oofor(intj=O;j<index;j++)

ocoutV<*(MatrixA+i*index+j)<<

ocout<<endl;

//派生类Linequ的实现

Linequ::Linequ(intdims):Matrix(dims)。〃派生类Linequ的构造函数

{。〃使用参数调用基类构造函数

sums=newdoub1e[dims];//动态内存分派

solu=newdouble[dims];

)

Linequ::~Linequ()〃派生类Linequ的析构函数

(

delete[]sums;〃释放内存

odelete[]solu;

)

voidLinequ::SetLinequ(double*a,double*b)。//设立线性方程组

2etMatrix(a);。//调用基类函数

for(inti=0;i<index;i++)

«sums[i]=b[i];

)

voidLinequ::PrintL()。//显示线性方程组

(

cout<<"Thelineequationis:"«end1;

»for(inti=0;i<index;i++)

{

ofor(intj=0;j<index;j++)

。cout«*(MatrixA+i*index+j)<<"";

ocout«""<<sums[i]«end1;

}

}

voidLinequ::ShowX()//输出方程组的解

(

cout«"Theresultis:"<<end1;

for(inti=0;i<index;i++)

(

ocout«"XL"«i«"]="«solu[i]«endl;

°)

}

intLinequ::Solve()。//全选主元高斯法求解方程

0int*js1,k,i,j,is,p,q;

doubled,t;

doub1e*MatrixB;//声明局部矩阵MatrixB

®MatrixB=newdouble[index*index];〃将矩阵MatrixA赋值

给MatrixB。

for(i=0;i<index*index;i++)

MatrixB[i]=MatrixA[i];

s=newint[index];//分派动态内存

1=1;

ofor(k=0;k<=index—2;k++)。//消去过程

(

9=0.0;

8for(i=k;i<=index-l;i++)//选取主元素

efor(j二k;jv=index-1;j++)

6{

“ot=fabs(MatrixB[i*index+j]);

if(t>d)

{d=t;js[k]=j;is=i;}

6}

“if(d+1.0==1.0)。〃主元素为零

°1=0;

。目se。//主元素互换

。if(js[k]!=k)

“ofor(i=0;iv=index—1;i++)

d0{

o。叩=i*index+k;

a。q=i*index+js[k];

。。t=MatrixB[p];MatrixB[p]=MatrixB[q];MatrixB[q]=t;

bbb)

gif(is!=k)

(

。for(j=k;jv=index—1;j++)

do{

o»p=k*index+j;

o叫=is*index+j;

<>»t=MatrixB[p];MatrixB[p]=Matrix[q];Matri

xB[q]=t;

°)

。。4=sums[k];sums[k]=sums[is];sums[is]=t;

0}

00)

Oif(l==0)”/若主元素为零,求解失败

(

。®delete[]js;

ocout«”failn«endl;

return0;

dd=MatrixB[k*index+k];。//归一化计算

for(j=k+l;j<=index-1;j++)

°{

p=k*index+j;

8bMatrixB[p]=MatrixB[p]/d;

0)

esums[k]=sums[k]/d;

for(i=k+1;i<=index-l;i++)〃消去计算

。{

or(j=k+1;j<=index-l;j++)

(

gp=index*i+j;

3。MatrixB[p]=MatrixB[p]-MatrixB[i*index+k]^MatrixB[k*

index+j];

°}

asums[i]=sums[i]-MatrixB[i*index+k]*sums[k];

}

0)

bd=MatrixB[(index-l)*index+index_1];

if(fabs(d)+1.0==1.0)

°{

。delete[]js;

8cout«Mfailn<<end1;

oreturn0;

0)

<>solu[index-l]=sums[index-1]/d?//回代过程

for(i=index-2;i>=0;i--)

{

®t=0.0;

for(j=i+1;jv=index-l;j++)

ot=t+MatrixB[i*index+j]*solufj];

®solu[i]=sums[i]—t;

}

®js[index-l]=index-1;

ofor(k=index-l;k>=0;k-----)

°if(js[k]!=k)

6{

。t=so1u[k];so1u[k]=solu[js[k]];solufjs[k]]=t;

J

gde1ete[]js;

oreturn1;

)

在类的成员函数实现过程中,派生类的构造函数使用参数调用了基类的构造

函数,为矩阵动态分派了内存空间。而派生类的析构函数同样也调用了基类的析

构函数,只是整个调用过程中完全是由系统内部完毕。基类的保护数据成员,通

过公有派生之后,在派生类中是以保护成员的身份出现的,派生类的成员函数可

以自由地进行访问。

全选主元高斯消去法求解函数返回值为整数,正常完毕之后,返回值为1,非

正常结束后,返回值为0,根据函数的返回值,就可以判断求解过程的完毕情况。

4.3主函数设计

//main.cpp主函数

#include"1inequ.h"

intmain()”/主函数

(

doub1ea[]=。。〃系数矩阵

(

-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);1/方程右端项

oLinequequl(4);//定义一个四元方程组对象

«equ1.SetLinequ(a,b);〃设立方程组

»equl.PrintL();»〃输出方程组

if(equ1.Solve())>//求解方程组

equl.ShowX();。//输出方程组的解

else

»cout<<"Fail"«endl;//求解失败

«return1;

}

在程序的主函数部分,选择了一个四元方程组作为一个实际例子来验证算

法。方程组的系数及右端项数据都使用一维数组来存储。一方面定义一个四元方

程组对象equl,在定义过程中调用派生类的构造函数,通过派生类的构造函数,

又调用了基类的构造函数,对进一步求解动态分派了内存。接着给方程组的系数

和右端项赋初值,把我们选定的方程组输入到新定义的方程组对象equl中。对象

成员函数PrintL、Solve和ShowX分别完毕了输出方程组、求解方程组和输

出求解结果的任务。

5DOS界面程序运营结果及分析

5.1程序运营结果

程序运营结果如图2所示。

图2程序运营结果

从图2中可以看出,程序可以实现全选主元高斯消去法对于线性方程组的求

解,但是,对于求解结果的对的性问题却无法获知,为了可以验证求解结果的对的

性,考虑将求解结果x带入原方程Ax=b中,假如满足原方程,即说明求解结果是

对的的,否则,说明求解存在问题,需对程序进行进一步调试分析。

为此,

温馨提示

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

评论

0/150

提交评论