【项目4 - 查成绩】
(1)score1.txt提供了某大学两个班某次测验的数据,包括每位同学的学号及成绩。
请编程序,输入学号,查找出该同学的成绩。
提示1:可以定义两个int型数组,其中一个n存放学号,另一个s存放成绩,可以保证两个数组中,元素下标相同,对应的是同一位同学。例如n[18]值为3123,s[18]为98,说明学号为3123的同学成绩为98。
提示2:因为数据无序,运用顺序查找算法,在n数组中依据学号进行查找,在s数组中对应下标的值则为其成绩。例如,通过在n中的查找,得出学号为3123的同学的下标为18,则其成绩为s[18]。
下面是完成应用的部分代码,已经能够输出成绩清单。请在此基础上实现有关的函数:
int main() { int num[200], score[200]; //分别保存学号和成绩 int count; //代表学生人数 int index; //代表查找到的学生的下标 int key; count = readData(num, score); //将成绩数据从文件中读到数组中 printf("请输入要查找的学生学号:"); scanf("%d",&key); index = search(num, count, key); //在count个学生中查找学号为key的学生对应的下标 if(index<0) //输入的学号不存在时,index的值要求返回-1 printf("不存在学号为%d的同学\n",key); else printf("学号为%d的同学的成绩是:%d\n", key, score[index]); return 0; }[参考解答]
#include <stdio.h> #include <stdlib.h> int readData(int[], int []); int search(int[], int, int); int main() { int num[200], score[200]; //分别保存学号和成绩 int count; //代表学生人数 int index; //代表查找到的学生的下标 int key; count = readData(num, score); //将成绩数据从文件中读到数组中 printf("请输入要查找的学生学号:"); scanf("%d",&key); index = search(num, count, key); //在count个学生中查找学号为key的学生对应的下标 if(index>=count) printf("不存在学号为%d的同学\n",key); else printf("学号为%d的同学的成绩是:%d\n", key, score[index]); return 0; } int readData(int n[], int s[]) { int c=0; FILE *fp; fp = fopen("score1.txt","r"); if (fp==NULL) { printf("open file error!\n"); exit(0); } //读入数据 while(fscanf(fp,"%d%d",&n[c],&s[c])!=EOF) c++; fclose(fp); return c; } int search(int n[], int c, int k) { int i; for(i=0; i<c; i++) { if(n[i]==k) break; } if(i==c) i=-1; return i; }
(2)在实际工程中,为了让频繁执行的查询更快一些,常要求对数据进行排序,再进行查询。请改造程序:①在调用readData(num, score);读入数据后,立即调用自定义函数sort对两个数组进行排序(注意在排序需要交换时,应该同时交换两个数组中对应的值,以保证同一下标,对应的是同一个学生的学号和成绩);②这样,search函数可以实现为二分查找了;③改造main函数,支持多次的查找。
[参考解答]
#include <stdio.h> #include <stdlib.h> int readData(int[], int []); void sort(int[], int[], int); int search(int[], int, int); int main() { int num[200], score[200]; //分别保存学号和成绩 int count; //代表学生人数 int index; //代表查找到的学生的下标 int key; int yn=1; count = readData(num, score); //将成绩数据从文件中读到数组中 sort(num, score, count); //将保存学号和成绩的两个数组按学号排序 while(yn) //从文件中读出数据,就是要多次使用的,排序花的代价,也值了 { printf("请输入要查找的学生学号:"); scanf("%d",&key); index = search(num, count, key); //在count个学生中查找学号为key的学生对应的下标 if(index < 0) printf("不存在学号为%d的同学\n",key); else printf("学号为%d的同学的成绩是:%d\n", key, score[index]); printf("输入1继续,输入0结束..."); scanf("%d", &yn); } return 0; } int readData(int n[], int s[]) { int c=0; FILE *fp; fp = fopen("score1.txt","r"); if (fp==NULL) { printf("open file error!\n"); exit(0); } //读入数据 while(fscanf(fp,"%d%d",&n[c],&s[c])!=EOF) c++; fclose(fp); return c; } void sort(int n[], int s[], int c) { int i,j,t; for(j=0; j<c-1; j++) for(i=0; i<c-j-1; i++) if (n[i]>n[i+1]) //根据学号升序排序 { t=n[i]; //交换学号 n[i]=n[i+1]; n[i+1]=t; t=s[i]; //同步交换成绩 s[i]=s[i+1]; s[i+1]=t; } return; } int search(int n[], int c, int k) { int low,high,mid; int i; low=0; high=c-1; while(low<=high) { mid=(low+high)/2; if(k==n[mid]) { i=mid; break; } else if(k>n[mid]) low = mid + 1; else high = mid - 1; } if (low>high) i=-1; return i; }