《C语言及程序设计》实践参考——查成绩

返回:贺老师课程教学链接  项目要求

【项目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;
}
时间: 2024-09-10 21:11:11

《C语言及程序设计》实践参考——查成绩的相关文章

《C语言及程序设计》实践参考——学生成绩统计

返回:贺老师课程教学链接 [项目1-学生成绩统计] 每位同学的信息学号.姓名.C.高数.英语成绩.定义一个学生成绩的结构体数组,其中的数据成员包括学号(char num[13]).姓名(name).三门课的成绩(grade).总分(score).均分(average)). (1)从键盘上输入N名学生的信息(N定义为常变量): (2)求出每名同学的总分和均分,并存储在结构体数组中(可以读入过程中"顺便"计算): (3)输出每位同学的信息学号.姓名.总分和均分. 请参考下面的代码,将需要的

《C语言及程序设计》实践参考——学生成绩处理

返回:贺老师课程教学链接 [项目2-学生成绩处理] (1)定义学生结构体,在结构体数组中,输入了学生学号和两门课的成绩,计算均分后,输出成绩单,请在下面的程序基础上,将程序补充完整. #include <stdio.h> #define N 100 /*N表示最多允许的学生人数*/ struct Student { int num; //学号 int c; //C语言成绩 int math; //数学成绩 float aver; //两科均分 }; int main( ) { int n; /

《C++语言基础》实践参考—— 链表类

返回:贺老师课程教学链接  项目要求 [项目 - 链表类]动态链表也是程序设计中的一种非常有用的数据结构.可以说,是否能够理解有关操作的原理,决定了你是否有资格称为"科班"出身.在后续的专业基础课中,相关的内容还会从不同的角度,反复地认识,反复地实践.不过,在现阶段多些体验,也是很有必要的了.(1)阅读下面的程序,回顾一下动态链表,阅读程序过程中,请用笔画一画形成链表的过程中指针值的变化. #include <iostream> using namespace std; s

《C++语言基础》实践参考——指向学生类的指针

返回:贺老师课程教学链接 [项目4-指向学生类的指针] 设计一个学生类Student,数据成员包括学号(num)和成绩(score),成员函数根据需要自行设计(建议配备需要的set.get函数,以及必要的输入或输出,给出的代码中也可以找到需要成员函数的线索).在main函数中,要做到: 建立一个对象数组,通过初始化,设置5个学生的数据,要求: 用指针指向数组首元素,输出第1.3.5个学生的信息: 设计一个函数int max(Student *arr);,用指向对象的指针作函数参数,在max函数中

《C++语言基础》实践参考——考了语文数学的学生

返回:贺老师课程教学链接 [项目4 - 考了语文数学的学生]下面提供了类Stu的数据成员定义,和用于测试的main函数,参考如图的运行结果,完成类的定义,并用多文件形式组织程序 #include<iostream> using namespace std; class Stu { private: string name; //学生姓名 float chinese; //语文成绩 float math; //数学成绩 //接下去写 }; int main() { Stu s1,s2; s1.s

《C++语言基础》实践参考——旱冰场造价

返回:贺老师课程教学链接 [项目1 - 旱冰场造价] 有一个圆形的旱冰场地,场地内抹水泥,造价为每平方米M元,围栏用木条围成,每米造价N元,输入旱冰场半径,用程序计算出其造价. 一级提示: 先定义类,确定其数据成员和成员函数.在这里要定义的旱冰场类,实际我们只关心其面积和周长,根据面积计算场地内抹水泥的造价,根据周长计算围栏的造价.有了类的定义,在main函数中定义该类对象,调用成员函数即可以完成求解.二级提示: 实际上,对于旱冰场,我们只关心它就是一个圆.这就是设计中抓住了本质.于是,设计一个

《C++语言基础》实践参考——复数模板类

返回:贺老师课程教学链接 [项目6-复数模板类]    阅读教材例10.1.该例实现了一个复数类,但是美中不足的是,复数类的实部和虚部都固定只能是double型的.可以通过模板类的技术手段,设计Complex,使实部和虚部的类型为定义对象时指定的实际类型.    (1)要求类成员函数在类外定义.    (2)在此基础上,再实现减法.乘法和除法    你可以使用的main()函数如下. int main( ) { Complex<int> c1(3,4),c2(5,-10),c3; //实部和虚

《C++语言基础》实践参考——Josephus(约瑟夫环)问题

返回:贺老师课程教学链接  项目要求 [项目-Josephus(约瑟夫环)问题]n个小孩子围成一圈,从第一个小孩子开始顺时针方向数数字,到第m个小孩子离开,这样反反复复,最终只剩下一个小孩子,求第几个小孩子留下?    提示:约瑟夫环即是一个首尾相连的链表,在建立好这个环以后,从头结点开始,每次间隔m孩子删除一个结点,直至只余下一个结点(删除了n-1个).     参考下面的代码,也可以自行设计类. //链表结点kid,其中number为这个人的编号 struct kid { int numbe

《C++语言基础》实践参考——友元类

返回:贺老师课程教学链接 [项目5-友元类]定义下面两个类的成员函数(为体验友元类,实际上本例并不一定是一个好的设计,将两个类的合并为一个DateTime,日期.时间都处理更好) class Date; //对Date类的提前引用声明 class Time { public: Time(int,int,int); void add_a_second(Date &); //增加1秒,1秒后可能会到了下一天,乃到下一月.下一年 void display(Date &); //显示时间,格式:月