HackerRank学生排序问题代码部分测试用例未通过求助
HackerRank学生排序问题:部分测试用例未通过的修复方案
问题概述
给定包含ID、FirstName、CGPA的学生信息列表,需按以下规则排序:
- CGPA降序
- CGPA相同时,按FirstName字典序升序
- FirstName相同时,按ID升序(ID无重复)
输入为学生总数N,后续N行每行包含ID、Name、CGPA;输出排序后的FirstName列表。提交的代码部分测试用例通过,部分失败。
输入输出示例
示例输入
5 33 Rumpa 3.68 85 Ashis 3.85 56 Samiha 3.75 19 Samara 3.75 22 Fahim 3.76
示例输出
Ashis Fahim Samara Samiha Rumpa
提交的代码
import java.util.*; class Student{ private int id; private String fname; private double cgpa; public Student(int id, String fname, double cgpa) { super(); this.id = id; this.fname = fname; this.cgpa = cgpa; } public int getId() { return id; } public String getFname() { return fname; } public double getCgpa() { return cgpa; } } class CombinedComparator implements Comparator<Student>{ @Override public int compare(Student student1, Student student2){ int gpaComparison = Double.compare(student2.getCgpa(), student1.getCgpa()); if(gpaComparison==0){ int fNameComparison= student1.getFname().toLowerCase().compareToIgnoreCase(student2.getFname().toLowerCase()); if(fNameComparison==0){ return Integer.compare(student1.getId(), student2.getId()); } return fNameComparison; } return gpaComparison; } } //Complete the code public class Solution { public static void main(String[] args){ Scanner in = new Scanner(System.in); int testCases = Integer.parseInt(in.nextLine()); List<Student> studentList = new ArrayList<Student>(); while(testCases>0){ int id = in.nextInt(); String fname = in.next(); double cgpa = in.nextDouble(); Student st = new Student(id, fname, cgpa); studentList.add(st); testCases--; } Collections.sort(studentList, new CombinedComparator()); for(Student st: studentList){ System.out.println(st.getFname()); } } }
问题分析与修复
提交的代码核心排序逻辑方向正确,但存在两处细节问题导致部分测试用例失败:
1. 浮点数精度误差
使用double类型存储CGPA时,会因为二进制浮点数的精度限制导致误差。比如部分十进制有限小数会被存储为近似值,导致比较结果不符合预期。题目明确CGPA最多两位小数,需用精确数值类型处理。
2. 字符串比较冗余
题目说明Name仅含小写英文字母,无需同时调用toLowerCase()和compareToIgnoreCase()——compareToIgnoreCase()本身已忽略大小写,额外的toLowerCase()属于冗余操作,虽不影响结果,但可能引发不必要的字符串对象创建。
修复后的代码
import java.util.*; import java.math.BigDecimal; class Student{ private int id; private String fname; private BigDecimal cgpa; public Student(int id, String fname, BigDecimal cgpa) { this.id = id; this.fname = fname; this.cgpa = cgpa; } public int getId() { return id; } public String getFname() { return fname; } public BigDecimal getCgpa() { return cgpa; } } class CombinedComparator implements Comparator<Student>{ @Override public int compare(Student student1, Student student2){ // CGPA降序比较 int gpaComparison = student2.getCgpa().compareTo(student1.getCgpa()); if(gpaComparison == 0){ // 名字字典序升序(题目明确全小写,直接用compareTo) int fNameComparison = student1.getFname().compareTo(student2.getFname()); if(fNameComparison == 0){ // ID升序比较 return Integer.compare(student1.getId(), student2.getId()); } return fNameComparison; } return gpaComparison; } } public class Solution { public static void main(String[] args){ Scanner in = new Scanner(System.in); int testCases = Integer.parseInt(in.nextLine()); List<Student> studentList = new ArrayList<>(); while(testCases > 0){ int id = in.nextInt(); String fname = in.next(); // 直接读取字符串转为BigDecimal,避免double精度损失 BigDecimal cgpa = new BigDecimal(in.next()); Student st = new Student(id, fname, cgpa); studentList.add(st); testCases--; } Collections.sort(studentList, new CombinedComparator()); for(Student st : studentList){ System.out.println(st.getFname()); } in.close(); } }
修复说明
- 精确数值处理:改用
BigDecimal存储CGPA,读取时直接以字符串形式解析,彻底避免浮点数精度误差。 - 优化字符串比较:移除冗余的
toLowerCase()调用,直接使用compareTo()完成字典序比较(符合题目Name仅含小写的约束)。
内容的提问来源于stack exchange,提问作者Kavindu Gamage
相关产品推荐
相关产品推荐

