C++对参赛结果处理(共29页)_第1页
C++对参赛结果处理(共29页)_第2页
C++对参赛结果处理(共29页)_第3页
C++对参赛结果处理(共29页)_第4页
C++对参赛结果处理(共29页)_第5页
已阅读5页,还剩25页未读 继续免费阅读

下载本文档

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

文档简介

1、精选优质文档-倾情为你奉上课程设计报告题目:对参赛结果分数进行处理 仙仙剑2013/6/19 C+课程设计实验报告(有所删减)一、 实验题目:对参赛结果分数进行处理二、 实验时间:2013/6/172013/6/20三、 实验地点:四、 实验要求: 参赛选手n人(n>1),评委m人(m>2),评委给每一选手打一个分数score(分数score为小于等于10的一个正实数)。选手的最后得分lastScore计算方法为(1)m<9时,去掉一个最高分和一个最低分后另m-2个得分的平均值。(2)m9时,去掉两个最高分和两个最低分后另m-4个得分的平均值。假设事先已经建立了text型的数

2、据文件f1.txt,其中依次记录着n个选手的编号(一个正整数)、姓名(一个字符串)以及m个评委给出的得分。请编制程序,依次从数据文件f1.txt中读入n个选手的有关信息,而后按上述规定方法计算出每一个选手的最后得分,而且往屏幕上以及另一个text型文件f2.txt中同时输出如下形式的结果信息。 假设参赛选手人数n=5,评委人数m=7,磁盘文件f1.txt中的初始数据为:1 zhangjin 8.8 9.3 7.9 8.7 8.9 9.7 9.22 lintao 8.9 8.2 8.6 8.8 8.5 9.1 9.33 guojian 8.9 8.4 8.7 8.6 8.6 8.4 8.64 m

3、aling 7.9 8.3 8.5 8.6 8.5 8.9 8.35 liuyifan 9.5 9.1 9.8 9.2 9.0 9.5 8.9那么,程序执行后,屏幕显示结果以及磁盘文件f2.txt中的结果均应该为:- 参赛号    姓 名     最高分    最低分   累积分    最后得分-  1  zhangjin    9.7   

4、60; 7.9    44.9     8.98  2    lintao     9.3     8.2   43.9      8.78  3   guojian     8.9  &#

5、160;  8.4   42.9      8.58  4    maling     8.9     7.9    42.2      8.44  5  liuyifan     9.8  

6、;   8.9   46.3      9.26-思考:可进一步考虑找出比赛的第1至第k名,也在屏幕以及f2.txt中同时输出相关的结果信息(k小于等于n,并规定若多个选手最后得分相同时,则有效分(即已删除原来的最高分后)中最高分高者名次优先)。五、 问题分析:首先,应该在某个磁盘建立好一个名为f1.txt的文件(如:E:f1.txt),并把数据写在文件中。然后读取其中数据,将数据储存在一些变量中,接着进行各种运算,包括排名的操作,最后输出在屏幕上,并写在f2.txt(如:E:f2.t

7、xt)中。 但是,有一个问题,如何确定参赛的人数,以及每个选手对应的裁判人数。如果数据都像题目中给的那样,人数就是5人,裁判都是7人就容易了。如果事先不知道参赛的人数,并且每个人对应的裁判人数不确定,比如第1个选手有5个裁判打分,第2个选手有10个裁判打分,又该如何去做?做程序是给别人用的,它要实现:当别人随便拿来一个相关文件,就能运行本程序进行操作,得出结果;而不是先打开文件,确定参赛人数和裁判人数,然后修改程序代码。那么,很明显,我们要设法计算出参赛的人数(也就是文件的行数),还要计算出每位选手对应的裁判人数(也就是一行中去掉编号和姓名,剩下的数据的个数),这两个功能当然要靠函数来实现。将

8、这两个函数写好后,其他的问题都将迎刃而解。六|、结构分析 本程序是对文件的操作,因此不涉及类的继承和派生,只需要写一个关于参赛选手信息的文件操作的类即可。七·实现流程 从宏观上来说,因为本程序相对较大,较为正式,因此打算写成多个文件的形式,要用到条件编译;当然,菜单也是必不可少的,至少要有两级菜单,要有循环,能够返回上一级菜单,如果不按退出键,程序不会自动退出(不像平时那样运行完结果就直接退出程序)。 从微观的实现细节来看:(1) 要定义一个类,我首先想到的是定义一个参赛选手的类,里面有编号、姓名、以及各种数据,然后建立对象数组,赋值并运算。但是,对象数组的大小是多少?这个大小是计算

9、出来的,而数组的定义要求有具体数值,Classname an;是无法通过编译的!此外,排序时要用到的次高分也要储存起来,它能放在类的数据成员吗?如果放在类里面,如何用构造函数进行初始化?不说次高分,其他的编号、姓名等数据的初始化都是个问题,这些数据要在构造函数中一一赋值会相当繁琐,不易编写代码,因而用这种方法面临着一定的难度。不如换一个角度来思考,本程序是对文件的相关操作,参赛选手的数据是在文件中读取的,因而不如做一个关于文件的类,而此类的数据成员仅为文件名及地址,因为要操作一个文件,只需要文件名和地址,而其他的数据则是从文件中获取的,把它们存储在一些变量中,然后进行相关操作,不把它们列为类数

10、据成员。另外,文件的行数N由于要在很多地方用到,因而也将其列入数据成员,在构造函数中要对其进行初始化,这个赋值比第一种方法中的赋值要轻松不少。(2) 即便是使用第二种方法定义一个文件操作的类,也要定义一个结构体数组,这个结构体中并不是存放原始文件中每个参赛选手的所有数据,而是存放编号、姓名、最高分、最低分、累积分、最后得分、次高分这些需要输出到屏幕和写入文件的数据。这些数据是通过从文件中读取并计算然后赋值得来的。在读取文件中数据的过程中,先定义2个string类型的变量来存放编号和姓名,然后定义float类型的数组来存放裁判所打的分数,这时,问题又来了,数组的长度是多少?数组长度必须是常数才能

11、通过编译,由于这个原因,决定采用向量容器,定义vector<float>tempScore(M);来存放这些数据,M为裁判的人数,由函数计算得来。接下来的工作就是将这些数据进行排序,可以调用系统的sort函数(要加头文件#include<algorithm>),以sort(tempScore.begin(),tempScore.end();的形式来调用;也可以自己写排序函数,如冒泡法、选择法等,然后取tempScore0为最低分,tempScoreM-1为最高分,调用累计函数AddSum(tempScore,M);算出累积分,调用最后得分函数LastScore(leij

12、isum(tempScore,M),M)算出最后得分,这些较为简单,不在赘述。之后便是将最高分、最低分、累计分、最后得分输出在屏幕上并写在文件f2.txt中。(3) 前面说了很多,一直没有说到重点,文件行数(参赛人数)N以及裁判人数M究竟是如何计算出来的,这才是关键问题的所在。 计算文件行数函数原型为LineSumNum(const char *filename),在打开文件之后用getline(buf,sz)函数进行逐行读取数据,其中sz定义为const int sz=80;buf定义为char bufsz;再定义一个整型变量linenum来统计行数,每读一行,linenum就+1,最后返回

13、linenum的值。但是,此法的局限性在于sz=80,如果文件的一行过长,则此法会出现问题,在调试中发现屏幕上不显示任何数据,如果将sz的数值写的过大,则会浪费内存。 计算裁判人数的函数原型为JudgerSumNum(int n),n为第n行(从0开始计数)首先打开文件,计算第1位选手对应的参赛人数要读取第1行数据,计算第2位要跳过第1行读取第2行,计算第3位要跳过前2行·····假设我们从第0行开始计数,第0行跳0行,第1行跳1行,第2行跳2行·····这样我们便可以得出第n位选手(从0开始计

14、数)需要跳过的行数,它就等于n,这可以做一个循环,然后getline即可。跳过的意思是:读取但没有其他操作,目前我不知道如何让文件指针直接指向某一行,因此采用这种较笨的方法。跳过这些行之后,终于到了我们需要操作的这一行,接下来就要将数据存储。首先定义两个string类型的变量存储编号和姓名,接下来定义vector<float>tempdata(20);来存储数据。定义judgernum来统计裁判的人数,每读取一个数据judgernum+1,当if(tempdatak2='0')break;停止,然后返回judgernum-2(本来认为返回judgernum-1,但在

15、调试中发现judgernum-2才是正确结果),但最后一行返回judgernum-1.这样,第n行有几个裁判就确定了。 (4) 接下来讲一下排序的问题。首先要定义vector<float> cigaoscore(N);来存储次高分,具体做法与前面类似,不再赘述。定义结构体数组(结合向量容器)vector<struct playersdata> stu(N);然后对其数据成员编号、姓名、最高分、最低分、累计分、最后得分、次高分进行赋值。调用事先已经写好的冒泡排序函数BubbleSort(vector<struct playersdata> & stu,

16、int n),先按最后得分排序,若最后得分相同,再按次高分进行排序。最后输出排序的结果即可。十、源代码 注:(1)进入程序之前,在E盘要有f1.txt的文件,否则系统会提示无法打开文件。文件中要有数据。在本文档末尾提供了f1.txt的内容范例,新建一个文本文档>重命名为”f1.txt”>将内容直接拷贝到f1.txt>将f1.txt放在E盘;也可以自己建立f1.txt的文件,依次输入编号(数据)、姓名(数据)、分数(数据),数据之间用空格隔开,但不能有多余空格,每个人的分数不能超过18个,否则可能出现错误,姓名用英文字母,不要过长,否则可能使数据不能对齐,影响美观。 (2)运行

17、程序时,右击标题栏,点击“属性”>点击“字体”选项>点击“新宋体”>点击“24”号字体>点击“确定”,观赏效果可能会好一点,也可根据个人喜好及计算机配置进行调节。 (以下程序在VC6.0上编译通过)/PlayersRecordOPerate.h#ifndef _PLAYERSRECORDOPERATE_H#define _PLAYERSRECORDOPERATE_H#include<iostream>#include<fstream>#include<string> #include<vector>#include<

18、algorithm>#include<assert.h>using namespace std;class PlayersRecordOperate /定义一个关于参赛选手信息的文件操作类private:struct playersdata /定义一个关于参赛选手信息结构体(注意:还没有定义结构体变量) string name; int num; float scoremax; float scoremin; float scoresum; float scoreend; float scorecigao; ;int N; /N为总行数(即参赛人数) void HeadFig

19、ure(); /表头1void HeadFigure2(); /表头2void EndFigure(); /表尾1public:const char *filename1; /分别定义要读取和写入的文件名const char *filename2;PlayersRecordOperate(const char *fn1,const char *fn2); /带两个参数的构造函数void MenuMain(); /菜单void MenuSmall1(); /次级菜单1void MenuSmall2(); /次级菜单2void SurfaceMenuS(); /次级菜单界面void Readfil

20、e(); /读取并输出文件信息int LineSumNum(const char *filename); /计算文件的行数(即参赛人数)int JudgerSumNum(int n); /计算裁判的人数,n为第n行(从第0行开始)float AddSumScore(vector<float>& temp,int n); /计算累积分(根据裁判人数去掉最高分和最低分之后)float LastScore(float addsumscore,int n);/计算最后得分,n为裁判人数void BubbleSort(vector<struct playersdata>

21、& stu,int n); /冒泡法排序(由大到小)void CalculateRecord(); /计算输出各位选手的得分情况int SortPlayerNum(); /需要排序的人数void ScoreSort(); /对各位选手进行排名;#endif/PlayersRecordOperate表头.cpp#include "PlayersRecordOperate.h" PlayersRecordOperate:PlayersRecordOperate(const char *fn1,const char *fn2):filename1(fn1),filenam

22、e2(fn2) /带两个参数的构造函数(初始化列表) N=LineSumNum(filename1); void PlayersRecordOperate:HeadFigure() /表头1 cout<<"-"<<endl; cout<<"参赛号"<<" "<<"姓 名"<<" "<<"最高分"<<" "<<"最低分"<&l

23、t;" "<<"累积分"<<" "<<"最后得分"<<endl; cout<<"-"<<endl; ofstream out; out.open(filename2); out<<"-"<<endl; out<<"参赛号"<<" "<<"姓 名"<<" "

24、<<"最高分"<<" "<<"最低分"<<" "<<"累积分"<<" "<<"最后得分"<<endl; out<<"-"<<endl; out.close(); void PlayersRecordOperate:HeadFigure2() /表头2 ofstream out; out.open(filename2,i

25、os:app); cout<<"-"<<endl; out<<"-"<<endl; cout<<"名 次"<<" "<<"姓 名"<<" "<<"最后得分"<<" "<<"次高分"<<endl; cout<<"-"<<endl; o

26、ut<<"名 次"<<" "<<"姓 名"<<" "<<"最后得分"<<" "<<"次高分"<<endl; out<<"-"<<endl; out.close(); void PlayersRecordOperate:EndFigure() /表尾1 cout<<"-"<<e

27、ndl; ofstream out; out.open(filename2,ios:app); out<<"-"<<endl; out.close(); /PlayersRecordOperate菜单.cpp#include "PlayersRecordOperate.h" void PlayersRecordOperate:MenuMain() /菜单 cout<<endl<<endl<<endl<<endl; cout<<" *"<<e

28、ndl; cout<<" 欢迎进入参赛结果处理系统"<<endl; cout<<" *"<<endl; cout<<endl; cout<<" 1.查看原始数据"<<endl; cout<<" 2.计算得分情况并排名"<<endl; cout<<" 3.退出程序"<<endl; cout<<endl; cout<<" *"

29、<<endl; cout<<endl; cout<<"请选择您想要的操作:"void PlayersRecordOperate:MenuSmall1() /次级菜单1 cout<<endl; SurfaceMenuS(); float keypress,temp; cin>>keypress; temp=keypress; switch(int(keypress) case 1:system("cls"); if(temp!=int(keypress) cout<<"提示:

30、输入的数据不能为小数!系统自动替您转化为整型。"<<endl; MenuMain(); break;case 2: if(temp!=int(keypress) cout<<"提示:输入的数据不能为小数!系统自动替您转化为整型。"<<endl; exit(0);default:system("cls"); Readfile();cout<<endl;cout<<endl; cout<<"提示:输入有误!请重新输入。"<<endl;MenuSm

31、all1(); void PlayersRecordOperate:MenuSmall2() /次级菜单2 SurfaceMenuS(); float keypress,temp; cin>>keypress; temp=keypress; switch(int(keypress) case 1:system("cls"); if(temp!=int(keypress) cout<<"提示:输入的数据不能为小数!系统自动替您转化为整型。"<<endl; MenuMain(); break;case 2:if(temp!

32、=int(keypress) cout<<"提示:输入的数据不能为小数!系统自动替您转化为整型。"<<endl; exit(0);default:system("cls"); cout<<"提示:您输入的数据无效!系统替您返回主菜单。"<<endl;MenuMain(); void PlayersRecordOperate:SurfaceMenuS() /次级菜单界面 cout<<"接下来请选择您的操作:"<<endl<<endl;

33、 cout<<"1.返回主菜单"<<endl; cout<<"2.退出程序"<<endl<<endl; cout<<"请输入相应数字:"/PlayersRecordOperate文件初步处理.cpp#include "PlayersRecordOperate.h" void PlayersRecordOperate:Readfile() /读取并输出文件信息ifstream in;in.open(filename1);if(!in)cout&l

34、t;<"无法打开文件"<<endl;exit(0);in.seekg(0,ios:beg); /将文件指针移至文件开始位置cout<<in.rdbuf()<<endl;in.close();int PlayersRecordOperate:LineSumNum(const char *filename)/计算文件的行数(即参赛人数) ifstream infile; infile.open(filename); if(!infile) cout<<"无法打开文件"<<endl; exit(

35、0); const int sz=80; char bufsz; int linenum=0; /记录行数 while(!infile.eof() infile.getline(buf,sz); /读取一行 linenum+; infile.close(); return linenum; int PlayersRecordOperate:JudgerSumNum(int n) /计算裁判的人数,n为第n行(从第0行开始) ifstream infile; infile.open(filename1); if(!infile) cout<<"无法打开文件"<

36、;<endl; exit(0); const int sz=80; char bufsz; for(int k=0;k<n;k+) /计算跳过的行数,第0行跳0行,第1行跳1行. infile.getline(buf,sz); int judgernum=0; /定义变量统计裁判员人数 string word2; /跳过编号和姓名 infile>>word0; infile>>word1; vector<float>tempdata(20);/定义向量容器用来存放接下来的一些数据,裁判人数不得超过18人 for(int k2=0;k2<20

37、;k2+) infile>>tempdatak2; judgernum+; if(tempdatak2='0')break; infile.close(); if(n=N-1) /如果是最后一行,返回 judgenum-1 return judgernum-1; else return judgernum-2; float PlayersRecordOperate:AddSumScore(vector<float>& temp,int n)/计算累积分(根据裁判人数去掉最高分和最低分之后) /n为裁判人数 float sum=0; if(n<

38、;9) for(int i=1;i<n-1;i+) /裁判人数<9人,分别去掉1个最高分和最低分 sum=sum+tempi; else if(n>=9) /裁判人数>=9人,分别去掉2个最高分和最低分 for(int i=2;i<n-2;i+) sum=sum+tempi; return sum; float PlayersRecordOperate:LastScore(float addsumscore,int n)/计算最后得分,n为裁判人数 float tLastscore; if(n<9) tLastscore=addsumscore/(n-2);

39、 else if(n>=9) tLastscore=addsumscore/(n-4); return tLastscore; void PlayersRecordOperate:BubbleSort(vector<struct playersdata> & stu,int n)/冒泡法排序(由大到小) int i,j; struct playersdata temp,temp1; for(i=0;i<n-1;i+) for(j=0;j<n-1-i;j+) if(stuj.scoreend=stuj+1.scoreend)&&(stuj.s

40、corecigao<stuj+1.scorecigao) /如果两个选手的最后得分相等,则根据次高分进行排序 temp1=stuj; stuj=stuj+1; stuj+1=temp1; else if(stuj.scoreend<stuj+1.scoreend) temp=stuj; stuj=stuj+1; stuj+1=temp; /PlayersRecordOperate计算输出得分情况.cpp#include "PlayersRecordOperate.h" void PlayersRecordOperate:CalculateRecord() /计算

41、输出各位选手的得分情况 ifstream in; ofstream out; in.open(filename1); if(!in) cout<<"无法打开文件"<<endl; exit(0); out.open(filename2,ios:app); HeadFigure(); /画出表头 for(int i=0;i<N;i+) /通过循环输出每位选手的相关数据 const int M=JudgerSumNum(i); /定义符号常量M,存放某个选手对应的裁判人数 string word2; /定义数组存放编号和姓名 vector<fl

42、oat>tempScore(M); /定义一个向量容器存放每一位裁判给某个选手打的分数 in>>word0; /将序号及姓名放在word数组中 cout<<" "<<word0<<" " out<<" "<<word0<<" " in>>word1; cout<<word1<<"t" out<<word1<<"t" for(in

43、t j=0;j<M;j+) in>>tempScorej; /把每一位裁判给某位选手打的分数分别放入向量容器中 sort(tempScore.begin(),tempScore.end(); /调用系统函数对数组进行排序 cout.setf(ios:fixed); /定点形式显示浮点数 out.setf(ios:fixed); cout.precision(1); /保留1位小数 cout<<tempScoreM-1; /输出最高分 out.precision(1); out<<tempScoreM-1; cout<<"t&quo

44、t;<<tempScore0; /输出最低分 out<<"t"<<tempScore0; cout<<"t"<<AddSumScore(tempScore,M); /输出累积分 out<<"t"<<AddSumScore(tempScore,M); cout.precision(2); cout<<"t"<<LastScore(AddSumScore(tempScore,M),M)<<"

45、t"<<endl; /输出最后得分 out.precision(2); out<<"t"<<LastScore(AddSumScore(tempScore,M),M)<<"t"<<endl; EndFigure(); /画出表尾 out.close(); in.close();/PlayersRecordOperate名次排序.cpp#include "PlayersRecordOperate.h" int PlayersRecordOperate:SortPlay

46、erNum() /需要排序的人数 cout<<"请输入您想排名的人数"<<"("<<"k<="<<N<<"):"<<endl; float K; cin>>K; while(K<=0 | K>N | (K-int(K)!=0) cout<<"输入数据错误!请重新输入"<<"("<<"k<="<<N<

47、;<"):"<<endl; float K1; cin>>K1; K=K1; assert(K>0 && K<=N &&(K-int(K)=0) ); return K;void PlayersRecordOperate:ScoreSort() /对各位选手进行排名 vector<float> cigaoscore(N); /定义一个向量容器来存放每个人的次高分 ifstream in; in.open(filename1); if(!in) cout<<"无法打开文

48、件"<<endl; exit(0); for(int i=0;i<N;i+) /通过循环记录每位选手的相关数据 const int M=JudgerSumNum(i); /定义符号常量M,存放某个选手对应的裁判人数 string word2; /定义数组存放编号和姓名 vector<float>tempScore(M); /定义一个向量容器存放每一位裁判给某个选手打的分数 in>>word0; /跳过序号及姓名 in>>word1; for(int j=0;j<M;j+) in>>tempScorej; /把每一

49、位裁判给某位选手打的分数分别放入向量容器中 sort(tempScore.begin(),tempScore.end(); /调用系统函数对数组进行排序 if(M<9) cigaoscorei=tempScoreM-2; /保留次高分数 else if(M>=9)cigaoscorei=tempScoreM-3; in.close(); ifstream in2; ofstream out2; in2.open(filename2); out2.open(filename2,ios:app); for(int i2=0;i2<3;i2+) /跳过前三行的表头 const in

50、t sz=80; char bufsz; in2.getline(buf,sz); vector<struct playersdata> stu(N); /定义结构体数组(结合向量容器) for(int m=0;m<N;m+) /对结构体数组的每一个成员的具体内容进行赋值 string nameword; /定义一个字符串变量存放姓名 vector<float>tempData(5); /定义向量容器存放除姓名外的其他5个数据 in2>>tempData0; in2>>nameword; for(int i=1;i<5;i+) in2

51、>>tempDatai; =nameword; stum.num=int(tempData0); stum.scoremax=tempData1; stum.scoremin=tempData2; stum.scoresum=tempData3; stum.scoreend=tempData4; stum.scorecigao=cigaoscorem; int K; /需要排序的人数 K=SortPlayerNum(); HeadFigure2(); /画出表头2 /vector<struct playersdata> *p=& stu; /定

52、义指向结构体数组的指针 BubbleSort(stu,N); /调用排序函数,按分数由高到低进行排序 for(int i3=0;i3<K;i3+) /输出排序的结果 cout<<"第"<<i3+1<<"名:" out2<<"第"<<i3+1<<"名:" cout.precision(2); cout<<<<'t'<<stui3.scoreend; cout.precision(1); cout<<'t'<<stui3.scorecigao<<endl; out2.setf(ios:fixed); out2.precision(2); out2<<<<'t'<<stui3.scoreend; out2.setf(ios:fixed); out2.pre

温馨提示

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

评论

0/150

提交评论