学生成绩条形图统计问题及引力波的实验探测给我们的启示_第1页
学生成绩条形图统计问题及引力波的实验探测给我们的启示_第2页
学生成绩条形图统计问题及引力波的实验探测给我们的启示_第3页
学生成绩条形图统计问题及引力波的实验探测给我们的启示_第4页
学生成绩条形图统计问题及引力波的实验探测给我们的启示_第5页
已阅读5页,还剩52页未读 继续免费阅读

下载本文档

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

文档简介

东北大学计算机科学与工程学院数据结构课程设计报告题目学生成绩条形图统计问题课题组长课题组成员专业名称计算机科学与技术班级计算机1405指导教师2021年1月课程设计任务书题目:学生成绩条形图统计问题问题描述:条形图问题描述:给定n个数据,绘出表示这n个数据的条形统计图。即统计出这n个数据中有多少个不同的值,以及每个值出现的频率是多少。条形图常用于表示数据分布情况。例如,学生考试成绩统计、居民收入分布情况等。假设输入数据为正整数,利用二叉排序树完成输入数据频率统计。设计要求:设计基于二叉排序树的学生成绩条形图统计程序。(1)采用STL的二叉排序树等数据结构。(2)应用基本运算,设计算法求解。指导教师签字:年月日1课题概述 51.1课题任务 51.2课题原理 51.3相关知识 62需求分析 72.1课题调研 72.2用户需求分析 73方案设计 73.1总体功能设计 73.2数据结构设计 83.3函数原型设计 93.4主算法设计 103.5用户界面设计 123.6输入输出设计 134方案实现 144.1开发环境与工具 144.2程序设计关键技术 144.3个人设计实现 164.3.1刘诚阳设计实现 164.3.2姚伟设计实现 224.3.3杜宇设计实现 235测试与调试 245.1个人测试 245.1.1刘诚阳测试 245.1.2姚伟测试 285.1.3杜宇测试 285.2组装与系统测试 295.3系统运行 306课题总结 306.1课题评价 306.2团队协作 306.3个人设计小结 316.3.1刘诚阳设计小结 316.3.2姚伟设计小结 326.3.3杜宇设计小结 327附录 33A课题任务分工 33A-1课题程序设计分工 33A-2课题报告分工 34B课题设计文档 35B-1课程设计报告(电子版) 35B-2源程序代码(*.H,*.CPP) 35B-3工程与可执行文件 46B-4屏幕演示录像文件 46C使用手册 46C.1运行环境说明 46C.2操作说明 4635/461课题概述1.1课题任务【问题描述】条形图问题描述:给定n个数据,绘出表示这n个数据的条形统计图。即统计出这n个数据中有多少个不同的值,以及每个值出现的频率是多少。条形图常用于表示数据分布情况。例如,学生考试成绩统计、居民收入分布情况等。假设输入数据为正整数,利用二叉排序树完成输入数据频率统计。【设计要求】设计基于二叉排序树的学生成绩条形图统计程序。(1)采用STL的二叉排序树等数据结构。(2)应用基本运算,设计算法求解。1.2课题原理(1)STL类库的使用STL可分为容器(containers)、迭代器(iterators)、空间配置器(allocator)、配接器(adapters)、算法(algorithms)、仿函数(functors)六个部分。容器部分主要由头文件<vector>,<list>,<deque>,<set>,<map>,<stack>和<queue>组成。对于常用的一些容器和容器适配器(可以看作由其它容器实现的容器),可以通过表1.1总结一下它们和相应头文件的对应关系。表1.1STL中的各类容器序列式容器向量(vector)连续存储的元素<vector>列表(list)由节点组成的双向链表,每个结点包含着一个元素<list>双端队列(deque)连续存储的指向不同元素的指针所组成的数组<deque>容器适配器栈(stack)后进先出的值的排列<stack>队列(queue)先进先出的值的排列<queue>优先队列(priority_queue)元素的次序是由作用于所存储的值对上的某种谓词决定的的一种队列<queue>关联式容器集合(set)由节点组成的红黑树,每个节点都包含着一个元素,节点之间以某种作用于元素对的谓词排列,没有两个不同的元素能够拥有相同的次序<set>多重集合(multiset)允许存在两个次序相等的元素的集合<set>映射(map)由{键,值}对组成的集合,以某种作用于键对上的谓词排列<map>多重映射(multimap)允许键对有相等的次序的映射<map>本程序设计中仅用到了向量,但是作为学习了解,经过此次设计我们也对STL的运用有了一个初步了解。(2)调用Excel绘图通过对MFC添加Excel的类,以此来外调Excel进行绘图操作,从而实现条形图的绘制,也是本次设计的一个重点。Excel的类接口如表1.2所示。表1.2调用Excel需要添加到MFC中的接口类Excel接口导入类头文件说明_ApplicationCApplicatonApplication.hExcel应用程序WorkbooksCWorkbooksWorkbooks.h工作簿的容器,里面包括了Excel应用程序打开的所有工作簿_WorkbookCWorkbookWorkbook.h单个工作簿WorksheetsCWorksheetsWorksheets.h单个工作簿中的Sheet表格的容器,包括该工作簿中的所有Sheet_WorksheetCWorksheetWorksheet.h单个Sheet表格RangeCRangeRange.h一定数量的单元格,可对单元格进行单个或多个单元格进行操作添加上述类之后,就可以调用相应的Excel操作函数,实现对Excel的操作(当然,其中还有很多地方需要调试,并需要修改某些头文件)。1.3相关知识基本数据结构知识。主要包括二叉排序树结构的使用,树的先序、中序和后序遍历等算法。C++的类及实现。程序设计采用C++的类进行封装,核心程序和算法使用C++代码编写。(3)C++界面设计。使用MFC进行可视化编程的相关知识。(4)STL的使用。使用VisualC++6.0提供的STL类库。2需求分析2.1课题调研当今世界对数据的依赖已经到了无以复加的地步,同样对于数据的处理也同等的重要。考虑设计条形图统计程序是非常有意义的。实现对数据分区段统计处理的意义在于:能够将所获取的数据通过计算机自动的统计处理并导入excel绘制条形统计图,实现高效的数据处理过程,展现出直观的数据处理结果。2.2用户需求分析经过实际的调研,本程序需要满足用户的以下需求:输入规范的数据,可以计算得出正确的结果,即各个区段的统计结果。程序应该具有演示功能,并且可以进行调试。具有良好的健壮性,对于错误数据要有甄别能力。具有友好的人机交互界面,输入数据和输出数据要显示在界面上,并且能够调用excel绘制条形统计图,使统计结果一目了然。程序要具有键盘输入、随机输入和文件输入三种输入方式,并且能够将统计结果保存到系统磁盘中,即生成文本文件。程序要具有适当的操作提示,以及防止用户错误操作的避免措施。具有应用程序文件,用户可以双击运行直接使用。3方案设计3.1总体功能设计程序主要由以下几个功能模块组成:输入功能、输出功能、调用excel绘制条形统计图和实时显示数据的功能。其中,输入功能包括文件输入、随机输入和键盘输入三种输入方式;实时显示是指将统计数据时刻显示在窗口内;调用excel绘制条形统计图的功能时本程序独具特色的一项功能,能够使统计结果更加形象和直观,让用户一目了然,而且可以直接生成excel文件,方便快捷。程序的主要功能如图3.1所示。图3.1学生成绩条形图统计程序功能图3.2数据结构设计(1)二叉排序树结构体的设计统计程序的主要结构采用二叉排序树的结构,这样有利于对数据的快速访问与统计,二叉排序树的结构体设计如下:BST-grades:float-name:CString-leftIdx:int-rightIdx:int+voidMakeNode(vector<structBST>&v,intaData,CString&name)+voidsetleft(vector<structBST>&v,intcurrIndex,intaData,CString&name)+voidsetright(vector<structBST>&v,intcurrIndex,intaData,CString&name)+voidInsert(vector<structBST>&v,intaData,CString&name)+voidInTrav(vector<structBST>&v,intIdx,CString&s,int&n)+voidPreTrav(vector<structBST>&v,intIdx,int&a,int&b,int&c,int&d,int&e)+voidPostTrav(vector<structBST>&v,intIdx,int&a,int&b,int&c,int&d,int&e)+voidRandomIn(vector<structBST>&v,inti,CString&name,floatgrades)+doublegetRand()图3.2二叉排序树结构体图(2)Excel类的设计。由于Excel类中的成员函数过多,在此处只列举包含的类,而不列举成员函数和变量。_Application:publicCOleDispatchDriver_Chart:publicCOleDispatchDriver_Worksheet:publicCOleDispatchDriver_Workbook:publicCOleDispatchDriverWorkbooks:publicCOleDispatchDriverFont:publicCOleDispatchDriverRange:publicCOleDispatchDriverBorders:publicCOleDispatchDriverCharts:publicCOleDispatchDriverChartObject:publicCOleDispatchDriverChartObjects:publicCOleDispatchDriverInterior:publicCOleDispatchDriverWorksheets:publicCOleDispatchDriver图3.3Excel类设计类图3.3函数原型设计程序的函数原型设计和功能如表3.1所示。表3.1学生成绩条形图统计程序的函数原型和功能设计表函数原型功能描述voidMakeNode(vector<structBST>&v,intaData,CString&name)建立二叉排序树的头结点voidsetleft(vector<structBST>&v,intcurrIndex,intaData,CString&name)插入函数,在给定位置插入结点,成为左孩子voidsetright(vector<structBST>&v,intcurrIndex,intaData,CString&name)插入函数,在给定位置插入结点,成为右孩子voidInsert(vector<structBST>&v,intaData,CString&name)按排序方式搜索到确定位置,调用插入函数voidInTrav(vector<structBST>&v,intIdx,CString&s,int&n)中序遍历二叉排序树,判断输入的名字是否在树中存在voidPreTrav(vector<structBST>&v,intIdx,int&a,int&b,int&c,int&d,int&e)先序遍历二叉排序树,统计各分数段成绩分布voidPostTrav(vector<structBST>&v,intIdx,int&a,int&b,int&c,int&d,int&e)后序遍历二叉排序树,统计各分数段成绩分布voidRandomIn(vector<structBST>&v,inti,CString&name,floatgrades);doublegetRand()随机生成数据,输入到二叉排序树中voidCMyDlg::OnFile()图形界面,文件输入数据到二叉排序树的按钮,并实现功能voidCMyDlg::OnRandom()图形界面,随机输入的按钮,调用随机输入和一系列操作voidCMyDlg::OnType()图形界面,键盘输入的按钮voidCMyDlg::OnConfirm()图形界面,确定按钮,并将数据导入二叉排序树voidCMyDlg::OnClear()图形界面,初始化程序的按钮voidCMyDlg::OnExcel()图形界面,调用Excel相关功能的函数3.4主算法设计本程序所使用的主要算法是二叉排序树的插入和遍历,二叉排序树是是一棵空树,或者是具有下列性质的二叉树:(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值;(2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值;(3)左、右子树也分别为二叉排序树;(4)没有键值相等的结点。由于本程序是希望对学生成绩进行统计,而学生成绩出现值相等的情况并不少见,因此我们规定一颗广义的二叉排序树,即允许有键值相等的点,并且相等的点一定是在与它等值的点的左端分支上。二叉排序树的结点插入算法设计如图3.4所示。二叉排序树的先序遍历(这里以先序遍历为例)算法如图3.5所示。图3.4二叉排序树结点插入算法设计流程图图3.5二叉排序树先序递归遍历算法设计流程图3.5用户界面设计经过多方面的考虑,本程序决定采用MFC可视化编程,实现图形界面,为用户提供可视化的操作,确保了良好的人机交互功能,并且使得处理结果更加直观、明确。可视化图形界面的外观设计如图3.5所示。图3.5学生成绩条形图统计程序用户操作界面图MFC可视化界面类设计如图3.6所示。CMyDlg:publicCDialog-IDD:enum{IDD=IDD_MY_DIALOG}-fail:int-good:int-ok:int-perfect:int-soso:int-grade:float-name:CString-m_hIcon:HICON+CMyDlg(CWnd*pParent=NULL)+virtualvoidDoDataExchange(CDataExchange*pDX)+virtualBOOLOnInitDialog()+afx_msgvoidOnSysCommand(UINTnID,LPARAMlParam)+afx_msgvoidOnPaint()+afx_msgHCURSOROnQueryDragIcon()+afx_msgvoidOnFile()+afx_msgvoidOnRandom()+afx_msgvoidOnType()+afx_msgvoidOnConfirm()+afx_msgvoidOnClear()+afx_msgvoidOnExcel()+DECLARE_MESSAGE_MAP()图3.3界面类设计3.6输入输出设计程序设计了三种输入方式,分别为文件输入,随机输入和键盘输入,输出方式除了必要的输出数据到显示窗口之外,还通过外调Excel表格对数据进行处理,绘制条形统计图。如图3.7所示。图3.7程序的输入输出功能4方案实现4.1开发环境与工具开发环境:Windows10主要编程工具:VisualC++6.0CodeBlocks4.2程序设计关键技术二叉排序树的结点插入和遍历算法运用二叉排序树的存储结构,能够高效快速的处理数据,统计出各个分数段的学生成绩,而二叉排序树的关键操作是插入结点数据和对二叉排序树进行遍历。插入算法首先执行查找,找出被插结点的父亲结点,判断被插结点是其父亲结点的左、右儿子。将被插结点作为叶子结点插入,若二叉树为空。则首先单独生成根结点。遍历算法主要借用递归调用实现。具体设计算法在主算法设计中已经讲述,此处不再赘述。MFC可视化编程程序可视化能够使得用户获得更好的操作体验,使得计算结果更加明确、一目了然,同时MFC对于数据的输入限制,也使得程序的稳定性进一步提高。因此,运用MFC进行可视化编程十分重要。MFC类库为我们提供很多可以直接调运的函数,从而使可视化编程变得简单,MFC提供的主要类库如图4.1所示。图4.1MFC提供的可操作类库在本次设计中,我们主要用到的是控件类所提供的各种功能控件,绘图类中提供的描点连线功能,应用程序结构中的命令发送类和窗口类,可视对象类中的窗口类和视图类,以及数据类中的字符串类等。STL类库的使用本程序使用到的STL容器是向量(vector),将向量的类型设置为二叉排序树(BST),从而实现在二叉排序树在顺序表中的存储,便于树的判空和树中结点个数的统计的操作。二叉排序树在向量中的存储方式如图4.2所示。单个向量空间包含四个数据,左上角为标识信息,右上角为数据,左下角为左孩子位置标记,右下角为右孩子位置标记,当孩子不存在时,标记为-1。图4.2二叉排序树在向量中的存储图4.3个人设计实现4.3.1刘诚阳设计实现(1)结点插入具体算法的流程图在主算法设计中已给出,代码实现如下:voidInsert(vector<structBST>&v,intaData,CString&name)//插入数据,小的设置成左孩子,大的设置成右孩子{ if(v.size()==0) { cout<<"Noteisnotmadeyet.MakeNodefirst..."<<endl; return; } intcurrentIdx=0; while(currentIdx<v.size()) { if(aData<=v[currentIdx].grades) { if(v[currentIdx].leftIdx==-1) { setleft(v,currentIdx,aData,name); break; } else currentIdx=v[currentIdx].leftIdx; } else { if(v[currentIdx].rightIdx==-1) { setright(v,currentIdx,aData,name); break; } else currentIdx=v[currentIdx].rightIdx; } }}(2)二叉排序树的后序遍历代码实现:voidPostTrav(vector<structBST>&v,intIdx,int&a,int&b,int&c,int&d,int&e)//后序遍历,统计各个分数段的人数{ if(v[Idx].leftIdx!=-1) PostTrav(v,v[Idx].leftIdx,a,b,c,d,e); if(v[Idx].rightIdx!=-1) PostTrav(v,v[Idx].rightIdx,a,b,c,d,e); if(v[Idx].grades<60){ e++; } elseif(v[Idx].grades>=60&&v[Idx].grades<70){ d++; } elseif(v[Idx].grades>=70&&v[Idx].grades<80){ c++; } elseif(v[Idx].grades>=80&&v[Idx].grades<90){ b++; } else{ a++; }}(3)调用Excel函数代码实现:voidCMyDlg::OnExcel(){//通过调用EXCEL的绘图功能绘制学生成绩的条形统计图 inta=0,b=0,c=0,d=0,e=0,f=0; PreTrav(v,0,a,b,c,d,e); //变量的定义_Applicationapp;Workbooksbooks;_Workbookbook;Worksheetssheets;_Worksheetsheet;Rangerange;LPDISPATCHlpDisp;COleVariantvResult;CStringstr="";COleVariantcovTrue((short)TRUE),covFalse((short)FALSE),covOptional((long)DISP_E_PARAMNOTFOUND,VT_ERROR);//创建Excel2021服务器(启动Excel)if(!app.CreateDispatch("Excel.Application",NULL)){AfxMessageBox("CreateExcelservicefailure!");return;}//设置为FALSE时,后面的app.Quit();注释要打开//否则EXCEL.EXE进程会一直存在,并且每操作一次就会多开一个进程app.SetVisible(TRUE);books.AttachDispatch(app.GetWorkbooks(),true);//打开一个工作簿。 lpDisp=books.Open("E:\\test.xlsx",covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional);ASSERT(lpDisp);book.AttachDispatch(lpDisp);//得到Worksheetssheets.AttachDispatch(book.GetWorksheets(),true);//得到Worksheetsheet.AttachDispatch(sheets.GetItem(_variant_t((short)(1))));//得到全部Cellsrange.AttachDispatch(sheet.GetCells(),true); //设置列宽 range.AttachDispatch(sheet.GetRange(_variant_t("A1"),_variant_t("F3")),true);range.SetColumnWidth(_variant_t((long)20)); //设置行高 range.AttachDispatch(sheet.GetRange(_variant_t("A1"),_variant_t("F3")),true); range.SetRowHeight(_variant_t((long)25)); //合并单元格 range.AttachDispatch(sheet.GetRange(_variant_t("A1"),_variant_t("F1")),true);range.Merge(_variant_t((long)0));//往单元格里写入字符串数据行/列 range.SetItem(_variant_t((LONG)1),_variant_t((LONG)1),_variant_t("学生成绩各分数段统计数据"));range.SetItem(_variant_t((LONG)2),_variant_t((LONG)1),_variant_t("等级"));range.SetItem(_variant_t((LONG)3),_variant_t((LONG)1),_variant_t("人数")); range.SetItem(_variant_t((LONG)2),_variant_t((LONG)2),_variant_t("优")); range.SetItem(_variant_t((LONG)2),_variant_t((LONG)3),_variant_t("良")); range.SetItem(_variant_t((LONG)2),_variant_t((LONG)4),_variant_t("中")); range.SetItem(_variant_t((LONG)2),_variant_t((LONG)5),_variant_t("及格")); range.SetItem(_variant_t((LONG)2),_variant_t((LONG)6),_variant_t("不及格"));//往单元格里写入整形数据 range.AttachDispatch(sheet.GetRange(_variant_t("B3"),_variant_t("B3")),true);range.SetValue2(_variant_t((long)a)); range.AttachDispatch(sheet.GetRange(_variant_t("C3"),_variant_t("C3")),true);range.SetValue2(_variant_t((long)b)); range.AttachDispatch(sheet.GetRange(_variant_t("D3"),_variant_t("D3")),true);range.SetValue2(_variant_t((long)c)); range.AttachDispatch(sheet.GetRange(_variant_t("E3"),_variant_t("E3")),true);range.SetValue2(_variant_t((long)d)); range.AttachDispatch(sheet.GetRange(_variant_t("F3"),_variant_t("F3")),true);range.SetValue2(_variant_t((long)e));/*range.AttachDispatch(sheet.GetRange(_variant_t("A1"),_variant_t("A1")),true);range.SetColumnWidth(_variant_t((long)12));*///所有单元格居中显示range.AttachDispatch(sheet.GetCells(),true);range.SetHorizontalAlignment(_variant_t((long)-4108));//-4108:居中,-4131:靠左,-4152:靠右range.SetVerticalAlignment(_variant_t((long)-4108));//-4108:居中,-4160:靠上,-4107:靠下 doubleleft=200,top=160,width=450,height=260;_Chartchart;ChartObjectschartobjects;ChartObjectchartobject; lpDisp=sheet.ChartObjects(covOptional); ASSERT(lpDisp); chartobjects.AttachDispatch(lpDisp); chartobject=chartobjects.Add(left,top,width,height); chart.AttachDispatch(chartobject.GetChart()); chart.SetChartType(72);//xlXYScatterSmooth lpDisp=sheet.GetRange(COleVariant("B2"),COleVariant("F3")); ASSERT(lpDisp); VARIANTvar; var.vt=VT_DISPATCH; var.pdispVal=lpDisp; chart.ChartWizard(var,//Source.COleVariant((short)51),//GallerycovOptional,//Format:1~6.COleVariant((short)1),//PlotBy:指定系列中的数据是来自行(1)还是来自列(2). covOptional,//CategoryLabels.COleVariant((short)0),//SeriesLabels.COleVariant((short)FALSE),//HasLegend.COleVariant("学生成绩统计条形图"),//Title.covOptional,//CategoryTitle.covOptional,//ValueTitles.covOptional//ExtraTitle.);// book.Save();//保存Excel的内容// app.SetDisplayAlerts(false);//不弹出对话框询问是否保存//app.Quit();//退出//释放对象range.ReleaseDispatch();sheet.ReleaseDispatch();sheets.ReleaseDispatch();book.ReleaseDispatch();books.ReleaseDispatch();app.ReleaseDispatch(); }(4)其他函数代码实现:voidRandomIn(vector<structBST>&v,intn,CString&name,floatgrades){//随机数插入时的辅助判断函数 if(n==0){//第一个随机数作为跟结点插入 MakeNode(v,grades,name); } else{//其余随机数作为结点插入 Insert(v,grades,name); }}doublegetRand(){//BOXMULLER算法生成正态分布数 doubleu1=double(rand()%10000)/10000,u2=double(rand()%10000)/10000,r; r=75+10*sqrt(-2.0*(log(u1)/log(2.718281828)))*cos(2*3.141592654*u2); returnr;}4.3.2姚伟设计实现(1)二叉排序树插入节点代码实现:voidsetleft(vector<structBST>&v,intcurrIndex,intaData,CString&name)//生成左孩子{ intleftIndex=v.size(); v[currIndex].leftIdx=leftIndex; structBSTb; b.grades=aData; b.leftIdx=-1; b.rightIdx=-1; =name; v.push_back(b);}voidsetright(vector<structBST>&v,intcurrIndex,intaData,CString&name)//生成右孩子{ intrightIndex=v.size(); v[currIndex].rightIdx=rightIndex; structBSTb; b.grades=aData; b.leftIdx=-1; b.rightIdx=-1; =name; v.push_back(b);}(2)二叉排序树的先序遍历算法流程图在主算法设计中已经列举,代码实现如下:voidPreTrav(vector<structBST>&v,intIdx,int&a,int&b,int&c,int&d,int&e)//先序遍历,统计各个分数段的人数{ if(v[Idx].grades<60){ e++; } elseif(v[Idx].grades>=60&&v[Idx].grades<70){ d++; } elseif(v[Idx].grades>=70&&v[Idx].grades<80){ c++; } elseif(v[Idx].grades>=80&&v[Idx].grades<90){ b++; } else{ a++; } if(v[Idx].leftIdx!=-1) PreTrav(v,v[Idx].leftIdx,a,b,c,d,e); if(v[Idx].rightIdx!=-1) PreTrav(v,v[Idx].rightIdx,a,b,c,d,e);}4.3.3杜宇设计实现(1)生成跟结点代码实现:voidMakeNode(vector<structBST>&v,intaData,CString&name)//生成根节点{ structBSTb; b.grades=aData; b.leftIdx=-1; b.rightIdx=-1; =name; v.push_back(b);}(2)二叉排序树的中序遍历代码实现:voidInTrav(vector<structBST>&v,intIdx,CString&s,int&n)//中序遍历,检验是否有重名,有则令n为1{ if(v[Idx].leftIdx!=-1) InTrav(v,v[Idx].leftIdx,s,n); if(v[Idx].name==s){ n=1; } if(v[Idx].rightIdx!=-1) InTrav(v,v[Idx].rightIdx,s,n);}5测试与调试5.1个人测试5.1.1刘诚阳测试(1)插入结点测试图5.1二叉排序树插入结点测试图(2)图形界面操作测试图5.2图形界面测试图图5.3从文本中读取数据测试图图5.4从文本中成功读取数据图5.5随机输入数据测试图图5.6键盘输入数据测试图图5.7Excel统计功能测试图5.1.2姚伟测试(1)中序遍历测试是否有重名图5.8中序遍历检测是否有重名测试图5.1.3杜宇测试(1)生成根结点测试图5.9建立根结点测试图(2)先序遍历测试图5.10先序遍历统计成绩分布测试图5.2组装与系统测试经过对各个部分的组装,程序能够实现良好的运行。程序的测试记录如表5.1所示。表5.1系统测试记录表操作名称操作流程操作结果和输出文件输入点击文件输入按钮成功输入文件内容,并在界面显示数据和统计处理后的结果随机输入点击随机输入按钮成功输入随机数据,并在界面显示数据和统计处理后的结果键盘输入点击键盘输入按钮,逐个输入数据,重复操作,直到数据全部输入完为止成功输入数据,并随逐步输入的数据逐步显示数据和统计处理后的结果Excel统计点击Excel统计按钮成功调用Excel软件,将统计结果写入Excel中,并且绘制条形统计图清空点击清空按钮成功初始化程序5.3系统运行系统可以在Windows平台上平稳运行,各项功能都达到了预期效果,界面简洁,操作便捷。运行过程中不会出现出错崩溃的情况。对于一些需要完善的功能,我们在运行程序,并进行检测后,又再一次对相应功能进行了完善与增强,并对系统的界面进行了精心的布局,使之达到最好的用户体验效果。6课题总结6.1课题评价学生成绩条形图统计问题可以看作是一类统计问题,即得到大量的数据,需要对这些数据进行统计处理得出它们的分布趋势,也就是说看看这些数据都落在哪些区间内,并且众数是多少的问题,这和求数据的平均数一样具有现实意义。利用计算机代替人工处理大量数据,自然是非常有优势的,除了能够节约时间和节省劳动力外,程序的可重复使用性能够保证只要有数据,就可以在段时间内得到统计结果。对于本次研究性课题的设计,我们通过学习STL标准类库并且使用STL类来进行编程,使得自己的编程能力得到了提高,解决问题的方式更加多元化。而且通过利用MFC框架外调Excel进行数据统计处理的设计也使得我们这次的课题任务圆满完成,总之,这是一次非常有意义的课题设计经历,我们收获良多。6.2团队协作我们团队在组团完成后,即刻就课题题目的选择问题进行了深刻的讨论,经由组长建议和组员的一致同意,我们最终选定了“学生成绩条形图统计”这个设计课题作为B题。在完成A题设计之后,我们组便进行了B题的整体框架和具体功能的讨论与研究。组长提出了该系统应该具有的功能并做记录,与组员们进行讨论,综合建议和信息,制定了总体的设计框架和系统具备的功能。随后,组长查阅了相关的资料,并绘制了所设计系统的功能图,以及在网上参考了别人设计的同类型的相关程序,并且将这些资料一并发给了组员,大家课余时间自行研究,最后再汇总交流经验与想法。隔日,大家一起进行了详细的分工明确,确定了我们的设计最终要实现什么样的功能,并进一步细致化,分类成一个个的函数,将函数的设计分配给每一个人。刘诚阳作为组长,负责整个程序的走向,函数设计包括界面的设计,二叉排序树的设计,文件输入输出的设计,调用Excel统计的设计,以及可视化操作设计等等;姚伟作为组员,主要负责二叉排序树的插入和中序遍历检验重复名字这一部分的设计;杜宇作为组员,主要负责二叉排序树根结点的建立和先序遍历统计分数区间的设计。任务分工完成后,大家都回去查找相关资料,潜心研究,独立完成各自的设计任务。每次上机课的时候,我们都会在一起讨论研究,进一步明确设计所要实现的具体目标,解决代码编写过程中的编写错误或者是当时设计时出现的纰漏。经过组内人员的共同努力,最后我们顺利地完成了此次程序设计任务,实现了学生成绩条形图统计课题要求。更为珍贵的是,通过团队合作,我们学会了团队开发模式,注重交流,分享经验,从彼此身上学到了很多,也为自己能在团队中贡献一份力量感到由衷的开心。6.3个人设计小结6.3.1刘诚阳设计小结在课程设计的两周时光中,我深刻地体会到了自学能力的重要性。着手程序的总体设计时,我发现课堂上学习的知识还远远不够,很多东西都需要自己临时查阅并学以致用,例如需要使用MFC可视化编程,需要使用STL类库,需要学习如何通过程序调用Excel表格等等。很多不懂的地方都是靠自己的不断尝试与摸索,凭借老师和同学的帮助,以及查阅相关资料,在网络上寻找答案,再自己一点点调试,才最终完成了这个实验设计。通过对STL的学习,我较为全面的了解到了STL类库的实现方式,并且感受到了它给编程所带来的方便,收获良多。可视化编程的实现因为有了A题的学习基础,在B题上并没有遇到太大的难题,只是需要不断的调试,来使程序达到最好的运行效果,减少错误的出现。最棘手的问题莫过于使用程序调用Excel操作了,这个问题困扰了我很久,直到快要进行验收的前两天才得以解决。因为临近期末,需要考试的科目很多,复习也赶得很紧,但是为了实现这个功能,我还是花了一天的时间去尝试,最后事实证明这时间花的是值得的。其实说到最终有效的时间也就是下午的一个小时而已,而在整个上午,都是一无所获,时间都花费在了搜索方法上,通过百度、论坛等各种途径。幸运的是在下午终于找到了合适的解决方法和部分讲解,通过学习尝试最终实现了调运Excel的功能,十分感谢这些素未谋面的网络上的共同学习者们。最后感谢在程序设计中给予我帮助的同学们和老师们,有了你们的建议和指导,我们这个团队才能不断完善设计,找到程序的Bug,并最终设计出一个相对完备的学生成绩条形图统计程序。6.3.2姚伟设计小结在本课程设计中,我明白了理论与实际应用相结合的重要性,并提高了自己组织数据及编写大型程序的能力。培养了基本的、良好的程序设计技能以及合作能力。这次课程设计同样提高了我的综合运用所学知识的能力。并对VC有了更深入的了解。《数据结构》是一门实践性很强的课程,上机实习是对学生全面综合素质进行训练的一种最基本的方法,是与课堂听讲、自学和练习相辅相成的、必不可少的一个教学环节。上机实习一方面能使书本上的知识变“活”,起到深化理解和灵活掌握教学内容的目的;另一方面,上机实习是对学生软件设计的综合能力的训练,包括问题分析,总体结构设计,程序设计基本技能和技巧的训练。此外,还有更重要的一点是:机器是比任何教师更严厉的检查者。因此,在“数据结构”的学习过程中,必须严格按照老师的要求,主动地、积极地、认真地做好每一个实验,以不断提高自己的编程能力与专业素质。6.3.3杜宇设计小结通过本次课程设计,对二叉树的概念有了一个新的认识,在学习离散数学的时候,总觉得二叉树是很抽象的东西,但是在学习了《数据结构》这门课程之后,我慢慢地体会到了其中的奥妙,二叉树能够在计算机中存在,首先要捕捉他有哪些具体化、数字化的信息,比如说权值、叶子个数等,这也就说明了想要把生活中的信息转化到计算机中必须用数字来完整的构成一个信息库,而二叉排序树的更是一件很巧妙的事情。在计算机中实现一个很简单的想法就需要涉及到很多专业知识,为了完成设计,在前期工作中,基本都是以学习二叉排序树的基本操作和STL类库为主。有了这次课程设计的经验和教训,我能够很清楚的对自己定一个合适的水平,而且在这次课程设计中我学会了运用二叉排序树对数据进行存储和处理。通过这段时间的课程设计,我认识到数据结构是一门比较难的课程。需要多花时间上机练习。这次的程序训练培养了我实际分析问题、编程和动手能力,使我掌握了程序设计的基本技能,提高了我适应实际,实践编程的能力。

总的来说,这次课程设计让我获益匪浅,对数据结构也有了进一步的理解和认识。7附录A课题任务分工A-1课题程序设计分工课题程序设计分工学号姓名程序设计函数原型、类功能说明20213712刘诚阳(1)typedefstructBST(2)CMyDlg(3)voidInsert(vector<structBST>&v,intaData,CString&name)(4)voidPostTrav(vector<structBST>&v,intIdx,int&a,int&b,int&c,int&d,int&e)(5)voidRandomIn(vector<structBST>&v,inti,CString&name,floatgrades);doublegetRand()(6)voidCMyDlg::OnFile()(7)voidCMyDlg::OnRandom()(8)voidCMyDlg::OnType()(9)voidCMyDlg::OnConfirm()(10)voidCMyDlg::OnClear()(11)voidCMyDlg::OnExcel()(1)二叉排序树结构体(2)MFC类,包含可视化操作的一系列函数(3)按排序方式搜索到确定位置,调用插入函数(4)后序遍历二叉排序树,统计各分数段成绩分布(5)随机生成数据,输入到二叉排序树中(6)图形界面,文件输入数据到二叉排序树的按钮,并实现功能(7)图形界面,随机输入的按钮,调用随机输入和一系列操作(8)图形界面,键盘输入的按钮(9)图形界面,确定按钮,并将数据导入二叉排序树(10)图形界面,初始化程序(11)图形界面,调用Excel相关功能的函数20213719姚伟(1)voidsetleft(vector<structBST>&v,intcurrIndex,intaData,CString&name)(2)voidsetright(vector<structBST>&v,intcurrIndex,intaData,CString&name)(3)voidInTrav(vector<structBST>&v,intIdx,CString&s,int&n)(1)插入函数,在给定位置插入结点,成为左孩子(2)插入函数,在给定位置插入结点,成为右孩子(3)中序遍历二叉排序树,判断输入的名字是否在树中存在20213706杜宇(1)voidMakeNode(vector<structBST>&v,intaData,CString&name)(2)voidPreTrav(vector<structBST>&v,intIdx,int&a,int&b,int&c,int&d,int&e)(1)建立二叉排序树的头结点(2)先序遍历二叉排序树,统计各分数段成绩分布A-2课题报告分工课题报告分工章节内容完成人1课题概述1.1课题任务1.2课题原理1.3相关知识刘诚阳2需求分析2.1课题调研2.2用户需求分析刘诚阳3方案设计3.1总体功能设计3.2数据结构设计3.3函数原型设计3.4输入输出设计3.5主算法设计3.6用户界面设计刘诚阳4方案实现4.1开发环境与工具4.2程序设计关键技术4.3个人设计实现4.3.1刘诚阳设计实现4.3.2姚伟设计实现4.3.3杜宇设计实现刘诚阳姚伟杜宇5测试与调试5.1个人测试5.1.1刘诚阳个人测试5.1.2姚伟个人测试5.1.3杜宇个人测试5.2组装与系统测试5.3系统运行刘诚阳姚伟杜宇6课题总结6.1课题评价6.2团队协作6.3个人设计小结6.3.1刘诚阳个人设计小结6.3.2姚伟个人设计小结6.3.3杜宇个人设计小结刘诚阳姚伟杜宇B课题设计文档B-1课程设计报告(电子版)B-2源程序代码(*.H,*.CPP)注:此处仅粘贴核心代码和MFC编程的相关代码,系统自动生成的代码与头文件不进行粘贴,Excel相关操作函数的.h文件和.cpp文件代码由于数量过于庞大,此处不粘贴,如需查看可在打包的压缩文件中浏览。////////////////////////////h.h////////////////////////////////////#include<iostream>#include<vector>#include<fstream>#include<string>#include<string.h>#include<math.h>#include<afx.h>usingnamespacestd;structBST{ floatgrades; CStringname; intleftIdx; intrightIdx;};voidMakeNode(vector<structBST>&v,intaData,CString&name);voidsetleft(vector<structBST>&v,intcurrIndex,intaData,CString&name);voidsetright(vector<structBST>&v,intcurrIndex,intaData,CString&name);voidInsert(vector<structBST>&v,intaData,CString&name);voidInTrav(vector<structBST>&v,intIdx,CString&s,int&n);voidPreTrav(vector<structBST>&v,intIdx,int&a,int&b,int&c,int&d,int&e);voidPostTrav(vector<structBST>&v,intIdx,int&a,int&b,int&c,int&d,int&e);voidRandomIn(vector<structBST>&v,inti,CString&name,floatgrades);doublegetRand();////////////////////////w.h//////////////////////////vector<structBST>v;inti=0;//////////////////////BST.cpp/////////////////////#include"h.h"#include"stdafx.h"voidMakeNode(vector<structBST>&v,intaData,CString&name)//生成根节点{ structBSTb; b.grades=aData; b.leftIdx=-1; b.rightIdx=-1; =name; v.push_back(b);}voidsetleft(vector<structBST>&v,intcurrIndex,intaData,CString&name)//生成左孩子{ intleftIndex=v.size(); v[currIndex].leftIdx=leftIndex; structBSTb; b.grades=aData; b.leftIdx=-1; b.rightIdx=-1; =name; v.push_back(b);}voidsetright(vector<structBST>&v,intcurrIndex,intaData,CString&name)//生成右孩子{ intrightIndex=v.size(); v[currIndex].rightIdx=rightIndex; structBSTb; b.grades=aData; b.leftIdx=-1; b.rightIdx=-1; =name; v.push_back(b);}voidInsert(vector<structBST>&v,intaData,CString&name)//插入数据,小的设置成左孩子,大的设置成右孩子{ if(v.size()==0) { cout<<"Noteisnotmadeyet.MakeNodefirst..."<<endl; return; } intcurrentIdx=0; while(currentIdx<v.size()) { if(aData<=v[currentIdx].grades) { if(v[currentIdx].leftIdx==-1) { setleft(v,currentIdx,aData,name); break; } else currentIdx=v[currentIdx].leftIdx; } else { if(v[currentIdx].rightIdx==-1) { setright(v,currentIdx,aData,name); break; } else currentIdx=v[currentIdx].rightIdx; } }}voidInTrav(vector<structBST>&v,intIdx,CString&s,int&n)//中序遍历,检验是否有重名,有则令n为1{ if(v[Idx].leftIdx!=-1) InTrav(v,v[Idx].leftIdx,s,n); if(v[Idx].name==s){ n=1; } if(v[Idx].rightIdx!=-1) InTrav(v,v[Idx].rightIdx,s,n);}voidPreTrav(vector<structBST>&v,intIdx,int&a,int&b,int&c,int&d,int&e)//先序遍历,统计各个分数段的人数{ if(v[Idx].grades<60){ e++; } elseif(v[Idx].grades>=60&&v[Idx].grades<70){ d++; } elseif(v[Idx].grades>=70&&v[Idx].grades<80){ c++; } elseif(v[Idx].grades>=80&&v[Idx].grades<90){ b++; } else{ a++; } if(v[Idx].leftIdx!=-1) PreTrav(v,v[Idx].leftIdx,a,b,c,d,e); if(v[Idx].rightIdx!=-1) PreTrav(v,v[Idx].rightIdx,a,b,c,d,e);}voidPostTrav(vector<structBST>&v,intIdx,int&a,int&b,int&c,int&d,int&e)//后序遍历,统计各个分数段的人数{ if(v[Idx].leftIdx!=-1) PostTrav(v,v[Idx].leftIdx,a,b,c,d,e); if(v[Idx].rightIdx!=-1) PostTrav(v,v[Idx].rightIdx,a,b,c,d,e); if(v[Idx].grades<60){ e++; } elseif(v[Idx].grades>=60&&v[Idx].grades<70){ d++; } elseif(v[Idx].grades>=70&&v[Idx].grades<80){ c++; } elseif(v[Idx].grades>=80&&v[Idx].grades<90){ b++; } else{ a++; }}voidRandomIn(vector<structBST>&v,intn,CString&name,floatgrades){//随机数插入时的辅助判断函数 if(n==0){ MakeNode(v,grades,name); } else{ Insert(v,grades,name); }}doublegetRand(){//BOXMULLER算法生成正态分布数 doubleu1=double(rand()%10000)/10000,u2=double(rand()%10000)/10000,r; r=75+10*sqrt(-2.0*(log(u1)/log(2.718281828)))*cos(2*3.141592654*u2); returnr;}///////////////////////////学生成绩条形图统计Dlg.cpp//////////////////////voidCMyDlg::OnFile(){ CStrings; CStringst="",str=""; str.Format("从文件读取了以下成绩:\r\n\r\n姓名成绩\r\n\r\n"); CStdioFilefile(_T("Datas.txt"),CFile::modeRead); floatgrades; inti=0,j=0; while(file.ReadString(s)){ CStrings1; while(AfxExtractSubString(s1,s,j,'')&&(j<2)){ switch(j){ case0: name=s1;break; case1: grades=_ttoi(s1);break; } j++; } i++; j=0; if(i==1){MakeNode(v,grades,name);} else{Insert(v,grades,name);} str+=name; st.Format("%.1f\r\n",grades); str+=st; } file.Close(); GetDlgItem(IDC_EDIT)->SetWindowText(str); PostTrav(v,0,perfect,good,soso,ok,fail); GetDlgItem(IDC_TYPE)->EnableWindow(false); GetDlgItem(IDC_RANDOM)->EnableWindow(false); GetDlgItem(IDC_FILE)->EnableWindow(false); GetDlgItem(IDC_CONFIRM)->EnableWindow(false); GetDlgItem(IDC_EXCEL)->EnableWindow(t

温馨提示

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

评论

0/150

提交评论