506. 相对名次(简单题)

本文介绍了一种算法,用于根据运动员的成绩确定其相对排名,并为前三名分配金牌、银牌和铜牌。该算法首先复制原始成绩数组,然后对其进行排序,使用HashMap将成绩映射到相应的排名或奖牌,最后返回排名结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述:
给出 N 名运动员的成绩,找出他们的相对名次并授予前三名对应的奖牌。前三名运动员将会被分别授予 “金牌”,“银牌” 和“ 铜牌”(“Gold Medal”, “Silver Medal”, “Bronze Medal”)。

(注:分数越高的选手,排名越靠前。)

示例 1:

输入: [5, 4, 3, 2, 1]
输出: [“Gold Medal”, “Silver Medal”, “Bronze Medal”, “4”, “5”]
解释: 前三名运动员的成绩为前三高的,因此将会分别被授予 “金牌”,“银牌”和“铜牌” (“Gold Medal”, “Silver Medal” and “Bronze Medal”).
余下的两名运动员,我们只需要通过他们的成绩计算将其相对名次即可。

提示:

N 是一个正整数并且不会超过 10000。
所有运动员的成绩都不相同。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/relative-ranks
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解法:

class Solution {
    public String[] findRelativeRanks(int[] nums) {
        int[] help = Arrays.copyOf(nums, nums.length);
        Arrays.sort(help);
        HashMap<Integer,String> map = new HashMap<>();
        int count = 1;
        for (int i = help.length - 1; i >= 0; i--) {
            if(count == 1) map.put(help[i],"Gold Medal");
            else if(count == 2) map.put(help[i],"Silver Medal");
            else if(count == 3) map.put(help[i],"Bronze Medal");
            else map.put(help[i],Integer.toString(count));
            count++;
        }
        String[] st = new String[nums.length];
        for (int i = 0; i < st.length; i++) {
            st[i] = map.get(nums[i]);
        }
        return st;
    }
}

重写Compartor,实现数组降序:

class Solution {
    public String[] findRelativeRanks(int[] nums) {
        Integer[] help = new Integer[nums.length];
        for (int i = 0; i < nums.length; i++) {
            help[i] = nums[i];
        }
        Comparator<Integer> cmp = new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;
            }
        };
        Arrays.sort(help,cmp);
        HashMap<Integer,String> map = new HashMap<>();
        for (int i = 0; i < help.length; i++) {
            if(i == 0) map.put(help[i],"Gold Medal");
            else if(i == 1) map.put(help[i],"Silver Medal");
            else if(i == 2) map.put(help[i],"Bronze Medal");
            else map.put(help[i],Integer.toString(i+1));
        }
        String[] st = new String[nums.length];
        for (int i = 0; i < st.length; i++) {
            st[i] = map.get(nums[i]);
        }
        return st;
    }
}

利用lambda表达式,完成数组降序排列:

class Solution {
    public String[] findRelativeRanks(int[] nums) {
        Integer[] help = new Integer[nums.length];
        for (int i = 0; i < nums.length; i++) {
            help[i] = nums[i];
        }
        Arrays.sort(help,(o1,o2)->o2-o1);
        HashMap<Integer,String> map = new HashMap<>();
        for (int i = 0; i < help.length; i++) {
            if(i == 0) map.put(help[i],"Gold Medal");
            else if(i == 1) map.put(help[i],"Silver Medal");
            else if(i == 2) map.put(help[i],"Bronze Medal");
            else map.put(help[i],Integer.toString(i+1));
        }
        String[] st = new String[nums.length];
        for (int i = 0; i < st.length; i++) {
            st[i] = map.get(nums[i]);
        }
        return st;
    }
}
1.功能需求 某班有最多不超过30人(具体人数由键盘输人)参加期末考试,最多不超过6门(具体门数由键盘输入)。请使用结构体数组、排序查找算法以及模块化程序设计方法编程实现如下菜单驱动的学生成绩管理系统: (1)输入每个学生的学号、姓和若干门课程考试成绩(2)计算每门课程的总分和平均分; (3)计算每个学生的总分和平均分; (4)按每个学生的总分由高到低排出名次表; (5)按每个学生的总分由低到高排出名次表; (6)按学号由小到大排出成绩表; (7)按姓的字典顺序排出成绩表; (8)按学号查询学生排及其考试成绩(9)按姓查询学生排及其考试成绩(10)按优秀(90~100)、良好(80~89)、中等(70~79)、及格(60~69)、不及格(0~59)5个类别,对每门课程分别统计每个类别的人数以及所占的百分比; (11)输出每个学生的学号、姓、各科考试成绩,以及总分和平均分; (12)将每个学生的记录信息写入文件; (13)从文件中读出每个学生的记录信息显示; 以下为选做功能: (14)向文件中追加1条记录; (15)删除文件中指定学号的记录; (16)修改文件中的某个学生的某门功课的成绩。 2.数据需求 每条记录包含学号(长整型)、姓(字符串)、多门课程的成绩(浮点型)、总成绩(浮点型)、平均成绩(浮点型)。 数据存储于文件StudentRecord.txt中,格式为每行一条记录;文件的第一行数据为学生人数和课程门数。 3.性能需求 系统响应快速,支持至少100条记录的高效处理。 界面友好,操作直观,提供菜单驱动交互。 三、系统设计 1.总体设计 模块划分: 系统采用模块化设计:每个功能模块封装为独立函数;全局数据通过结构体数组统一管理。 主菜单模块:提供功能入口,循环调用各子模块。 具体菜单要求如下: 1.Input record 2.Calculate total and average score of every course 3.Calculate total and average scored of every student 4.Sort in descending order by total score of every student 5.Sort in ascending order by total score of every student 6.Sort in ascending order by number 7.Sort in dictionary order by name 8.Search by number 9.Search by name 10.Statistic analysis for every course 11.List record 12.Write to a file 13.Read from a file 0.Exit Please enter your choice: 数据输入模块:实现学生信息由键盘录入与验证。 数据处理模块:对结构体数组stu进行按条件查询、排序。 文件操作模块:实现对文件中的数据进行读写、增删改等操作。2.数据结构设计 定义结构体Student: typedef struct Student { long num; // 学号 char name[MAX_LEN]; // 姓 float score[COURSE_NUM]; // 多门课程的成绩 float sum; //每个学生的总分 float aver; // 平均成绩 }STU; 3.算法设计 排序算法:选择排序实现按平均分排序。 查询算法:线性查找实现按学号/姓查询。 四、系统实现 1.主函数流程 int main(void) { char ch; int n = 0,m = 0; STU stu[STU_NUM]; printf("Input student number(n<%d):",STU_NUM); scanf("%d",&n); printf("Input course number(m<=%d):",COURSE_NUM); scanf("%d",&m); while(1) { ch = Menu(); //显示菜单,读取用户输入 switch(ch) { case 1 : ReadScore(stu,n,m); break; case 2: AverSumofEveryCourse(stu,n,m); break; case 3: AverSumofEveryStudent(stu,n,m); break; case 4: SortbyScore(stu,n,m,Descending); printf("\nSort in descending order by score:\n"); PrintScore(stu,n,m); break; case 5: SortbyScore(stu,n,m, Ascending); printf("\nSort in ascending order by score:\n"); PrintScore(stu,n,m); break; case 6: AsSortbyNum(stu,n,m); printf("\nsort in ascending order by number:\n"); PrintScore(stu,n,m); break; case 7: SortbyName(stu,n,m); printf("\nSort in dictionary order by name:\n"); PrintScore(stu,n,m); break; case 8: SearchbyNum(stu,n,m); break; case 9: SearchbyName(stu,n,m); break; case 10:StatisticAnalysis(stu,n,m); break; case 11:PrintScore(stu,n,m); break; case 12:WritetoFile(stu,n,m); break; case 13:ReadfromFile(stu,&n,&m); break; case 0:printf("End of program!"); exit(0); default:printf("Input error!"); } } return 0; } 2.各功能函数实现 (1)输入每个学生的学号、姓和若干门课程考试成绩(2)计算每门课程的总分和平均分; (3)计算每个学生的总分和平均分; (4)按每个学生的总分由高到低排出名次表; //按选择法将结构体数组stu的元素按总分升()序排序 void SortbyScore(STU stu[],int n,int m,int (*compare)(float a,float b)) { int i,j,k,t; for(i=0;i<n-1;i++) { k=i; for(j=i+1;j<n;j++) { if((*compare)(stu[j].sum,stu[k].sum)) k=j; } if(k!=i) { //说明:可整体交换两个结构体数组元素,也可以数组元素各成员逐一交换 } } } //使数据按升序排序 int Ascending(float a,float b) { return a<b; //这样比较决定了按升序排序,如果a<b, 则交换 } //使数据按降序排序 int Descending(float a,float b) { return a>b; //这样比较决定了按降序排序,如果a>b、则交换 } (5)按每个学生的总分由低到高排出名次表; (6)按学号由小到大排出成绩表; (7)按姓的字典顺序排出成绩表; (8)按学号查询学生排及其考试成绩(9)按姓查询学生排及其考试成绩(10)按优秀(90~100)、良好(80~89)、中等(70~79)、及格(60~69)、不及格(0~59)5个类别,对每门课程分别统计每个类别的人数以及所占的百分比; (11)输出每个学生的学号、姓、各科考试成绩,以及总分和平均分; (12)将每个学生的记录信息写入文件; (13)从文件中读出每个学生的记录信息显示; 五、测试与调试 1.测试用例 正常输入:输入有效学号、姓成绩,验证排序与查询功能。 异常输入:输入非数字成绩,验证错误提示机制。 说明: 1)可以使用多张测试用例表,对不同的功能模块进行测试。在测试用例表中给出正常与异常的测试数据进行功能测试。 2)也可以给出正常或异常测试的运行结果截图 2.调试问 文件读写错误:文件路径错误→统一使用相对路径检查权限。
最新发布
06-19
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值