例题4-6 师兄帮帮忙 UVa12412
感悟。
1、阅读书中题目,从网站下载英文原题,重点在看输出数据与格式。
2、开始编码,先搭函数框架,具体功能实现,待主体框架打好后,再进行。
3、程序测试比较繁琐,有较多的输出输出,有些接近现实的应用程序了。
4、add功能还算顺利,数据采用结构体数组的方式存储。
5、query功能,发现要添加要在结构体中继续添加一些数据,还需在add功能中添加相应数据的处理功能。
6、statistics功能,发现还要添加新的结构体,要在add功能中添加相应数据处理功能,真受不了啊。
7、学了一招,结构体初始化clwhole=(struct classinfo){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
8、一个功能一个功能的写,多次用到printf进行跟踪,有些错误,不靠跟踪是无法检查出的。
9、10.21下午,总算写好,能对上基本的输入输出,提交WA,估计要格式完全对上,开始对照格式进行修改。
10、改格式之前,重读英文原题,发现漏了Hint部分,马上照做,提交WA。
11、对照输入输出格式,详细修改一遍,提交WA。
12、暂时没辙,先放一放,看看中文书,有没什么没注意到的地方。
13、中文书阅读后,无论是分析还是解法,都与本人比较相似,暂无启发。
14、测试了一遍同名统计,发现统计中漏了提示语,补上,测时同名次通过,提交WA。
15、重新阅读英文文档,对照着功能进行测试,发现一处遗漏,
//print out all the matching students, in the same order they’re added to the database.
本人是按总分自大到小输出的,原文要求按添加顺序进行输出,
着手进行修改,在结构体中添加了int add;进行添加顺序记录,
修改相关处理int add的代码,
经输入输出验证通过,提交WA。
开始在网上搜索前人的经验了。
16、阅读博客http://blog.csdn.net/archya/article/details/38345101当数据库被清空后统计函数会出现除0的错误。对remove进行测试,发现删除同名时,只删除一次,马上进行修改。将数据库清空,确实出现除0错误。继续进行修改。提交WA。
17、得使试试对拍了。与AC程序对照输出,找到问题,处理int add出错,修改,继续对拍,完全对上,提交AC,时间2016.10.23 9:41,逆向工程做得不错,找到了解决问题的终极办法,但是,缺点是测试数据比较费劲。
附上AC程序,编译环境Dev C++4.9.9.2
388行
#include <stdio.h>
#include <string.h>
struct student{
int add;//加入顺序,多次WA,重读文档后,添加的新数据。
int rank;
char sid[30];
int cid;
char name[20];
int chinese;
int math;
int english;
int programming;
int sum;
float avr;
}stu[110],tmpstu;
struct classinfo{
float chinese_avr;
int chinese_p;
int chinese_f;
float math_avr;
int math_p;
int math_f;
float english_avr;
int english_p;
int english_f;
float programming_avr;
int programming_p;
int programming_f;
int passed_all;
int passed_3;
int passed_2;
int passed_1;
int passed_0;
int num;
}clinfo[110],clwhole;
int count=0;
//测试数据用,专门编写了print函数,用于调试。
void printstu(){
int i;
printf("stu %d\n",count);
for(i=0;i<count;i++){
printf("%d %d %s %d %s %d %d %d %d %d %.2f\n",stu[i].add,stu[i].rank,stu[i].sid,stu[i].cid,stu[i].name,stu[i].chinese,stu[i].math,stu[i].english,stu[i].programming,stu[i].sum,stu[i].avr);
}
}
void print(){
int i;
printf("stu %d\n",count);
for(i=0;i<count;i++){
printf("%d %d %s %d %s %d %d %d %d %d %.2f\n",stu[i].add,stu[i].rank,stu[i].sid,stu[i].cid,stu[i].name,stu[i].chinese,stu[i].math,stu[i].english,stu[i].programming,stu[i].sum,stu[i].avr);
}
printf("clinfo print\n");
for(i=0;i<110;i++){
if(clinfo[i].num>0){
printf("%.2f %d %d %.2f %d %d %.2f %d %d %.2f %d %d %d %d %d %d %d %d\n",clinfo[i].chinese_avr,clinfo[i].chinese_p,clinfo[i].chinese_f,clinfo[i].math_avr,clinfo[i].math_p,clinfo[i].math_f,clinfo[i].english_avr,clinfo[i].english_p,clinfo[i].english_f,clinfo[i].programming_avr,clinfo[i].programming_p,clinfo[i].programming_f,clinfo[i].passed_all,clinfo[i].passed_3,clinfo[i].passed_2,clinfo[i].passed_1,clinfo[i].passed_0,clinfo[i].num);
}
}
printf("clwhole print\n");
printf("%.2f %d %d %.2f %d %d %.2f %d %d %.2f %d %d %d %d %d %d %d %d\n",clwhole.chinese_avr,clwhole.chinese_p,clwhole.chinese_f,clwhole.math_avr,clwhole.math_p,clwhole.math_f,clwhole.english_avr,clwhole.english_p,clwhole.english_f,clwhole.programming_avr,clwhole.programming_p,clwhole.programming_f,clwhole.passed_all,clwhole.passed_3,clwhole.passed_2,clwhole.passed_1,clwhole.passed_0,clwhole.num);
}
void processing(){
int i,j;
//排序处理,冒泡排序,简单 ,总分自大到小
for(i=0;i<count;i++){
for(j=i+1;j<count;j++){
if(stu[i].sum<stu[j].sum){
tmpstu=stu[i];
stu[i]=stu[j];
stu[j]=tmpstu;
}
}
}
//编制rank
for(i=0;i<count;i++){
stu[i].rank=i+1;//正常排名
if(i>=1){//排名相同处理
if(stu[i].sum==stu[i-1].sum)
stu[i].rank=stu[i-1].rank;
}
}
//排序处理,冒泡排序,按添加先后进行排序。因打印是按添加顺序,而非分数高低。多次WA后,在此处进行修改
for(i=0;i<count;i++){
for(j=i+1;j<count;j++){
if(stu[i].add>stu[j].add){
tmpstu=stu[i];
stu[i]=stu[j];
stu[j]=tmpstu;
}
}
}
//编制statistcs
//初始化
memset(clinfo,0,sizeof(clinfo));
clwhole=(struct classinfo){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
for(i=0;i<count;i++){
j=stu[i].cid;
//chinese
clinfo[j].chinese_avr+=stu[i].chinese;
if(stu[i].chinese>=60)
clinfo[j].chinese_p++;
else
clinfo[j].chinese_f++;
//math
clinfo[j].math_avr+=stu[i].math;
if(stu[i].math>=60)
clinfo[j].math_p++;
else
clinfo[j].math_f++;
//english
clinfo[j].english_avr+=stu[i].english;
if(stu[i].english>=60)
clinfo[j].english_p++;
else
clinfo[j].english_f++;
//programming
clinfo[j].programming_avr+=stu[i].programming;
if(stu[i].programming>=60)
clinfo[j].programming_p++;
else
clinfo[j].programming_f++;
if(stu[i].chinese>=60&&stu[i].math>=60&&stu[i].english>=60&&stu[i].programming>=60){//全过
clinfo[j].passed_all++;
}else if(stu[i].chinese<60&&stu[i].math<60&&stu[i].english<60&&stu[i].programming<60){//全不过
clinfo[j].passed_0++;
}else if((stu[i].chinese<60&&stu[i].math>=60&&stu[i].english>=60&&stu[i].programming>=60)||(stu[i].chinese>=60&&stu[i].math<60&&stu[i].english>=60&&stu[i].programming>=60)||(stu[i].chinese>=60&&stu[i].math>=60&&stu[i].english<60&&stu[i].programming>=60)||(stu[i].chinese>=60&&stu[i].math>=60&&stu[i].english>=60&&stu[i].programming<60)){//只有一门没过,过了三门
clinfo[j].passed_3++;
}else if((stu[i].chinese>=60&&stu[i].math<60&&stu[i].english<60&&stu[i].programming<60)||(stu[i].chinese<60&&stu[i].math>=60&&stu[i].english<60&&stu[i].programming<60)||(stu[i].chinese<60&&stu[i].math<60&&stu[i].english>=60&&stu[i].programming<60)||(stu[i].chinese<60&&stu[i].math<60&&stu[i].english<60&&stu[i].programming>=60)){//过了一门
clinfo[j].passed_1++;
}else{//过了两门
clinfo[j].passed_2++;
}
clinfo[j].num++;
}
//班级序号不大于学生数,假定,不知是否正确,试试看。
for(i=1;i<=count;i++){
if(clinfo[i].num>0){//班级序号从1开始,而不是0,找到重大Bug i改称i+1
//whole
clwhole.chinese_avr+=clinfo[i].chinese_avr;
clwhole.math_avr+=clinfo[i].math_avr;
clwhole.english_avr+=clinfo[i].english_avr;
clwhole.programming_avr+=clinfo[i].programming_avr;
clwhole.num+=clinfo[i].num;
clwhole.chinese_p+=clinfo[i].chinese_p;
clwhole.chinese_f+=clinfo[i].chinese_f;
clwhole.math_p+=clinfo[i].math_p;
clwhole.math_f+=clinfo[i].math_f;
clwhole.english_p+=clinfo[i].english_p;
clwhole.english_f+=clinfo[i].english_f;
clwhole.programming_p+=clinfo[i].programming_p;
clwhole.programming_f+=clinfo[i].programming_f;
//clinfo
clinfo[i].chinese_avr/=clinfo[i].num;
clinfo[i].math_avr/=clinfo[i].num;
clinfo[i].english_avr/=clinfo[i].num;
clinfo[i].programming_avr/=clinfo[i].num;
//float处理
clinfo[i].chinese_avr+=1e-5;
clinfo[i].math_avr+=1e-5;
clinfo[i].english_avr+=1e-5;
clinfo[i].programming_avr+=1e-5;
// printf("count=%d cid=%d %d %d %d %d %d\n",count,i,clinfo[i].passed_all,clinfo[i].passed_3,clinfo[i].passed_2,clinfo[i].passed_1,clinfo[i].passed_0);
clinfo[i].passed_3+=clinfo[i].passed_all;
clinfo[i].passed_2+=clinfo[i].passed_3;
clinfo[i].passed_1+=clinfo[i].passed_2;
// printf("count=%d cid=%d %d %d %d %d %d\n",count,i,clinfo[i].passed_all,clinfo[i].passed_3,clinfo[i].passed_2,clinfo[i].passed_1,clinfo[i].passed_0);
//whole
clwhole.passed_all+=clinfo[i].passed_all;
clwhole.passed_3+=clinfo[i].passed_3;
clwhole.passed_2+=clinfo[i].passed_2;
clwhole.passed_1+=clinfo[i].passed_1;
clwhole.passed_0+=clinfo[i].passed_0;
}
}
//whole
if(clwhole.num!=0){//除0错误
clwhole.chinese_avr/=clwhole.num;
clwhole.math_avr/=clwhole.num;
clwhole.english_avr/=clwhole.num;
clwhole.programming_avr/=clwhole.num;
//float处理
clwhole.chinese_avr+=1e-5;
clwhole.math_avr+=1e-5;
clwhole.english_avr+=1e-5;
clwhole.programming_avr+=1e-5;
}
}
void add(){
int i;
while(1){
printf("Please enter the SID, CID, name and four scores. Enter 0 to finish.\n");
scanf("%s",stu[count].sid);
//输入为0,跳出循环
if(strcmp(stu[count].sid,"0")==0){
//printstu();
break;
}
scanf("%d%s%d%d%d%d",&stu[count].cid,stu[count].name,&stu[count].chinese,&stu[count].math,&stu[count].english,&stu[count].programming);
//查找 是否有重复
for(i=0;i<count;i++){
if(strcmp(stu[i].sid,stu[count].sid)==0)
break;
}
if(i==count){
stu[i].sum=stu[i].chinese+stu[i].math+stu[i].english+stu[i].programming;
stu[i].avr=stu[i].sum/4.0;
stu[i].add=i;//添加序列,从0开始。
count++;
}
else
printf("Duplicated SID.\n");
}
//数据处理
processing();
}
void remove(){
char s[30];
int del;
int i;
int j;
while(1){
printf("Please enter SID or name. Enter 0 to finish.\n");
scanf("%s",s);
if(strcmp(s,"0")==0){
//printstu();
break;
}
del=0;
if(s[0]>='A'&&s[0]<='Z'){//姓名
for(i=0;i<count;i++){
if(strcmp(stu[i].name,s)==0){
del++;
//自i+1开始,添加序列均自减1
for(j=i+1;j<count;j++){
stu[j].add--;
}
stu[i]=stu[count-1];
count--;
i--;
//printstu();
processing();//此句开始成功2016.10.23 9:33
}
}
}else{//sid
for(i=0;i<count;i++){
if(strcmp(stu[i].sid,s)==0){
del++;
//自i+1开始,添加序列均自减1
for(j=i+1;j<count;j++){
stu[j].add--;
}
stu[i]=stu[count-1];
count--;
break;
}
}
processing();
}
printf("%d student(s) removed.\n",del);
}
}
//print out all the matching students, in the same order they’re added to the database.
void query(){
int i;
int sum;
float avr;
char s[30];
while(1){
printf("Please enter SID or name. Enter 0 to finish.\n");
scanf("%s",s);
if(strcmp(s,"0")==0){
break;
}
if(s[0]>='A'&&s[0]<='Z'){//姓名
for(i=0;i<count;i++){
if(strcmp(stu[i].name,s)==0){
printf("%d %s %d %s %d %d %d %d %d %.2f\n",stu[i].rank,stu[i].sid,stu[i].cid,stu[i].name,stu[i].chinese,stu[i].math,stu[i].english,stu[i].programming,stu[i].sum,stu[i].avr);
}
}
}else{//sid
for(i=0;i<count;i++){
if(strcmp(stu[i].sid,s)==0){
printf("%d %s %d %s %d %d %d %d %d %.2f\n",stu[i].rank,stu[i].sid,stu[i].cid,stu[i].name,stu[i].chinese,stu[i].math,stu[i].english,stu[i].programming,stu[i].sum,stu[i].avr);
}
}
}
}
}
void ranking(){
printf("Showing the ranklist hurts students' self-esteem. Don't do that.\n");
}
void statistics(){
int select;
printf("Please enter class ID, 0 for the whole statistics.\n");
scanf("%d",&select);
if(select&&clinfo[select].num>0){//非0
printf("Chinese\nAverage Score: %.2f\nNumber of passed students: %d\nNumber of failed students: %d\n\n",clinfo[select].chinese_avr,clinfo[select].chinese_p,clinfo[select].chinese_f);
printf("Mathematics\nAverage Score: %.2f\nNumber of passed students: %d\nNumber of failed students: %d\n\n",clinfo[select].math_avr,clinfo[select].math_p,clinfo[select].math_f);
printf("English\nAverage Score: %.2f\nNumber of passed students: %d\nNumber of failed students: %d\n\n",clinfo[select].english_avr,clinfo[select].english_p,clinfo[select].english_f);
printf("Programming\nAverage Score: %.2f\nNumber of passed students: %d\nNumber of failed students: %d\n\n",clinfo[select].programming_avr,clinfo[select].programming_p,clinfo[select].programming_f);
printf("Overall:\n");
printf("Number of students who passed all subjects: %d\n",clinfo[select].passed_all);
printf("Number of students who passed 3 or more subjects: %d\n",clinfo[select].passed_3);
printf("Number of students who passed 2 or more subjects: %d\n",clinfo[select].passed_2);
printf("Number of students who passed 1 or more subjects: %d\n",clinfo[select].passed_1);
printf("Number of students who failed all subjects: %d\n\n",clinfo[select].passed_0);
}else{//0
// print();
printf("Chinese\nAverage Score: %.2f\nNumber of passed students: %d\nNumber of failed students: %d\n\n",clwhole.chinese_avr,clwhole.chinese_p,clwhole.chinese_f);
printf("Mathematics\nAverage Score: %.2f\nNumber of passed students: %d\nNumber of failed students: %d\n\n",clwhole.math_avr,clwhole.math_p,clwhole.math_f);
printf("English\nAverage Score: %.2f\nNumber of passed students: %d\nNumber of failed students: %d\n\n",clwhole.english_avr,clwhole.english_p,clwhole.english_f);
printf("Programming\nAverage Score: %.2f\nNumber of passed students: %d\nNumber of failed students: %d\n\n",clwhole.programming_avr,clwhole.programming_p,clwhole.programming_f);
printf("Overall:\n");
printf("Number of students who passed all subjects: %d\n",clwhole.passed_all);
printf("Number of students who passed 3 or more subjects: %d\n",clwhole.passed_3);
printf("Number of students who passed 2 or more subjects: %d\n",clwhole.passed_2);
printf("Number of students who passed 1 or more subjects: %d\n",clwhole.passed_1);
printf("Number of students who failed all subjects: %d\n\n",clwhole.passed_0);
}
}
void exit(){
}
int main(){
int choice;
do{
printf("Welcome to Student Performance Management System (SPMS).\n\n");
printf("1 - Add\n2 - Remove\n3 - Query\n4 - Show ranking\n5 - Show Statistics\n0 - Exit\n\n");
scanf("%d",&choice);
switch(choice){
case 1:
add();
break;
case 2:
remove();
break;
case 3:
query();
break;
case 4:
ranking();
break;
case 5:
statistics();
break;
case 0:
exit();
break;
}
}while(choice);
return 0;
}