67. 学生成绩排序

67. 学生成绩排序

成绩5开启时间2023年12月11日 星期一 08:00
折扣0.8折扣时间2023年12月31日 星期日 23:55
允许迟交关闭时间2024年01月7日 星期日 23:55

    大家参加了期末考试,成绩出来后老师要对 n 个学生进行成绩汇总和排序。要求程序按成绩降序进行排序。在排序过程中对于成绩相同的学生,要按照输入数据的顺序进行排列。例如:有5名学生的成绩:
zhang1,90
zhang2,91
zhang3,99
zhang4,91
zhang5,98

则排序结果应该为:
zhang3,99
zhang5,98
zhang2,91
zhang4,91
zhang1,90

请注意例题中“zhang2”和“zhang4”的排列顺序。

输入:
    第一行为将要输入的学生数量n
    从第二行起后面连续 n 行数据,每行为一名学生的姓名(长度不超过20个字符,不包括空格),考试成绩(int)

输出:
    排序后的结果。每行为一名学生的姓名和成绩。

测试输入期待的输出时间限制内存限制额外进程
测试用例 1以文本方式显示
  1. 5↵
  2. zhang1,90↵
  3. zhang2,91↵
  4. zhang3,99↵
  5. zhang4,91↵
  6. zhang5,98↵
以文本方式显示
  1. zhang3,99↵
  2. zhang5,98↵
  3. zhang2,91↵
  4. zhang4,91↵
  5. zhang1,90↵
1秒64M0
测试用例 2以文本方式显示
  1. 5↵
  2. zhang31,90↵
  3. zhang51,90↵
  4. zhang2,90↵
  5. zhang42,90↵
  6. zhang1,90↵
以文本方式显示
  1. zhang31,90↵
  2. zhang51,90↵
  3. zhang2,90↵
  4. zhang42,90↵
  5. zhang1,90↵
1秒64M0
测试用例 3以文本方式显示
  1. 1↵
  2. wang,100↵
以文本方式显示
  1. wang,100↵
1秒64M0

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX 20

struct Student {
    char name[MAX];
    int score;
};

int main() {
    int n;
    scanf("%d", &n);
    struct Student* students = (struct Student*)malloc(n * sizeof(struct Student));
    for (int i = 0; i < n; i++) {
        scanf(" %[^,],%d", students[i].name, &students[i].score);
    }

    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n - 1 - i; j++) {
            if (students[j].score < students[j + 1].score) {
                int temp = students[j].score;
                students[j].score = students[j + 1].score;
                students[j + 1].score = temp;
                char tempName[MAX];
                strcpy(tempName, students[j].name);
                strcpy(students[j].name, students[j + 1].name);
                strcpy(students[j + 1].name, tempName);
            }
        }
    }

    for (int i = 0; i < n; i++) {
        printf("%s,%d\n", students[i].name, students[i].score);
    }

    free(students);

    return 0;
}

使用strcpy的时候,记得是数组对数组,原因是

底层逻辑是C语言使用连续的内存块来存储结构体类型的数据。当你在循环中多次使用相同的内存位置来存储不同的数据时,后续的存储操作会覆盖之前的存储内容。为了避免这种情况,你应该为每个数据项分配独立的内存空间,例如使用字符数组来存储每个学生的名字,而不是将名字复制到相同的内存位置。(AI写的)

------

来优化一下,新学了qsort函数

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    char name[20];
    int score;
} Student;

// 比较函数,用于qsort排序
int compare(const void *a, const void *b) {
    Student *A = (Student *)a;
    Student *B = (Student *)b;
    
    if (A->score > B->score) return -1; // A的分数大于B的分数,返回-1,表示A在前
    if (A->score < B->score) return 1;  // A的分数小于B的分数,返回1,表示B在前
    
    return -1; // 如果分数相等,返回-1,表示A在前
}

int main() {
    int n;
    scanf("%d", &n);
    Student students[n];
    
    for (int i = 0; i < n; i++) {
        getchar(); // 读取换行符
        scanf("%[^,],%d", students[i].name, &students[i].score); // 读取姓名和分数
    }
    
    qsort(students, n, sizeof(Student), compare); // 使用qsort对学生数组进行排序
    
    for (int i = 0; i < n; i++) {
        printf("%s,%d\n", students[i].name, students[i].score); // 输出排序后的学生信息
    }
    
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值