洛阳理工学院课程设计报告课程名称数据结构课程设计设计题目成绩统计系统专业计算机科学与技术1. 问题描述给出n个学生的m门考试的成绩表,每个学生的信息由学号、姓名以及各科成绩组成。
对学生的考试成绩进行有关统计,并打印统计表。
2.基本要求(1)按总数高低次序,打印出名次表,分数相同的为同一名次;(2)按名次打印出每个学生的学号、姓名、总分以及各科成绩。
3、数据结构类型定义struct Student{char m_Name[20];unsigned int m_ID;float m_Score[m];};4. 总体设计(1)模块划分:<1>初始化函数: Node* Init();<2>直接插入法排序函数: float* Sort();<3>相同名次处理函数: int Del_Same();<4>打印函数void Display();<5>主函数:void main()2、组成框图:3、流程图<1>初始化函数: Node* Init(); <2>直接插入法:float* Sort();语文 数学 英语 物理处理相同分数排 序输入成绩输入学号输入姓名欢迎进入成绩统计系统<3>相同名次处理:int Del_Same(); <4>打印函数void Display();5. 详细设计1.声明一个结构体:typedef struct Student Node;2.录入数据将复制形式修改为指针访问形式,计算成绩总和写入到sum[]中。
3.打印,按名次从第一名到最后一名。
4.下直接插值排序法会用到"哨兵",nSize表示grade[]中实际元素的个数。
5.处理相同成绩的名次将sum[n]中的不重复的元素放到grade[n]中,函数返回grade[]中实际元素的个数。
测试数据:姓名语文数学英语物理黄54 53 52 51赵98 97 96 95李100 99 99 986. 测试与调试1、输入数据:2.打印成绩7. 源程序清单#include <stdio.h>#include <string>#include <float.h>#include <iostream> #include <iomanip>#define n 3/*学生数*/ #define m 4/*课程数*/ using namespace std; //---声明一个结构---- struct Student{char m_Name[20];unsigned int m_ID;float m_Score[m];};typedef struct Student Node;//------函数声明---------------------------Node* Init(Node* stu,const int cN,float* Asum,int nSum);float* Sort(float* Agrade,int nSize);int Del_Same(float* Asum,int nSum,float* Agrade,int nGreade);void Display(Student* stu,int nN,float* Asum,int nSum,float* Agrade,int nGreadeSize);//------函数实现---------------------------//----录入数据------Node* Init(Node* stu,const int cN,float* Asum,int nSum){char name[20];unsigned int id;float score[m];int i,j;for(i=0;i<n;++i){printf("请输入第%d/%d名学生的信息:\n ",i+1,n);printf("请输入姓名: ");scanf("%s",name);printf("\n请输入学号: ");scanf("%d",&id);for(j=0;j<m;++j){printf("\n录入第 %d/%d 门课程成绩:",j+1,m);scanf("%f",&score[j]);}printf("\n");//---赋值过程---------------strcpy((stu+i)->m_Name,name);//修改成指针访问形式. (stu+i)->m_ID=id;for(j=0;j<m;j++){(stu+i)->m_Score[j]=score[j];}//-------计算成绩总和写入到sum[]中--------*(Asum+i)=0.0;for(j=0;j<m;++j){(*(Asum+i))+=((stu+i)->m_Score[j]);}}//for(n)printf("成功!~数据录入完毕! ");return stu;}void Display(Node* stu,int nN,float* Asum,int nSum,float* Agrade,int nGreadeSize){//打印。
按名次从第一名到最后一名。
cout<<endl<<"=================================================================== ======"<<endl;cout<<"============================打印名次信息================================="<<endl;cout<<"========================================================================= "<<endl;cout<<"名次======学号======姓名======总分=====名科成绩===="<<endl;for(int i=0;i<nGreadeSize;++i){for(int j=0;j<n;++j){if(Asum[j]==Agrade[i]){cout<<setw(10)<<left<<i+1//名次。
<<setw(10)<<left<<stu[j].m_ID//学号。
<<setw(10)<<left<<stu[j].m_Name//姓名。
<<setw(10)<<left<<Asum[j];//总分。
for(int k=0;k<m;++k)cout<<setw(10)<<left<<stu[j].m_Score[k];//名科成绩。
}//cout<<endl;}}}float* Sort(float* Agrade,int nSize){//练习一下直接插值排序法。
会用到"哨兵"。
nSize表示grade[]中实际元素的个数。
for(int i=1;i<nSize;++i){Agrade[nSize]=Agrade[i];//将它放到哨兵里for(int j=i-1;j>=0;){if(Agrade[nSize]>Agrade[j])//从大到小的顺序。
一定要注意,是拿"哨兵"来与之比较才对的。
{Agrade[j+1]=Agrade[j];j--;}else{break;}}//for内Agrade[j+1]=Agrade[nSize];// 从哨兵中取出这个值来}//for 外return Agrade;}int Del_Same(float* Asum,int nSum,float* Agrade,int nGreade){//将sum[n]中的不重复的元素放到grade[n]中,函数返回grade[]中实际元素的个数。
int Find;//有无重复的标记:1为有,0为无。
int nElem=1;//gread[]中的实际元素个数。
Agrade[0]=Asum[0];for(int i=0;i<nSum;++i)//sum[]{for(int j=0;j<nElem;++j)//grade[]{if(Asum[i]==Agrade[j])//判断两个浮点数相等条件。
{Find=1;break;}else{Find=0;}}if(Find==0){Agrade[nElem]=Asum[i];nElem++;}}//for(最外)return nElem;}//------------void main(){Node Stu[n];Node* pStu;pStu=Stu;//声明n个Student对象的一个数组。
float sum[n],grade[n+1];//因为想在grade[]中用到直接插值排序法,要用到"哨兵"。
所以构造n+1.pStu=Init(pStu,n,sum,n);int nGrade_size;nGrade_size=Del_Same(sum,n,grade,n+1);float* pGrade=0;pGrade=Sort(grade,nGrade_size);Display(pStu,n,sum,n,grade,nGrade_size);}八、心得体会这次我抽到的题目很简单,但是这是指用基础的C语言写很简单。
如果想把本学期数据结构的知识应用到程序中还是很有挑战性的。
我采用的是直接插入排序法,刚开始把书上的程序照搬过来,结果发现有许多的错误。
改了很久才改对。
最难的是相同成绩处理的函数,我刚开始以为很简单,但是前面各个成绩采用的是指针结构体,很难处理,最后在网上查找了一下才对照着改正过来。
最后我学会的是可以先把数据输入数组内,在用指针直接指向数据就可以了,这样比输入数据时就用指针要简单的多。