智能成绩表---重点 覆写comparator排序的compare函数

小明来到某学校当老师,需要将学生按考试总分或单科分数进行排名,你能帮帮他吗?

输入描述
第 1 行输入两个整数,学生人数 n 和科目数量 m。

0 < n < 100
0 < m < 10
第 2 行输入 m 个科目名称,彼此之间用空格隔开。

科目名称只由英文字母构成,单个长度不超过10个字符。
科目的出现顺序和后续输入的学生成绩一一对应。
不会出现重复的科目名称。
第 3 行开始的 n 行,每行包含一个学生的姓名和该生 m 个科目的成绩(空格隔开)

学生不会重名。
学生姓名只由英文字母构成,长度不超过10个字符。
成绩是0~100的整数,依次对应第2行种输入的科目。
第n+2行,输入用作排名的科目名称。若科目不存在,则按总分进行排序。

输出描述
输出一行,按成绩排序后的学生名字,空格隔开。成绩相同的按照学生姓名字典顺序排序。

用例1
输入
3 2
yuwen shuxue
fangfang 95 90
xiaohua 88 95
minmin 100 82
shuxue
输出
xiaohua fangfang minmin
说明
按shuxue成绩排名,依次是xiaohua、fangfang、minmin

import java.util.Collections;
import java.util.HashMap;
import java.util.Scanner;
import java.util.Comparator;
import java.util.ArrayList;

class Student {
    public String name;
    public int rank[];
    // 设置一个学生类 设置未知元素个数的rank数组 记录 此学生的0-length-1门成绩
    Student(String name, int[] rank) {
        this.name = name;
        this.rank = rank;
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int countOfStudent = in.nextInt();
        // 学生人数
        int countOfSubject = in.nextInt();
        // 学科数量
        String[] subjectNames = new String[countOfSubject];
        // 存储所有学科名字
        HashMap<String,Integer> map = new HashMap<String,Integer>();
        // 学科名字 对应  rank的索引位置 
        ArrayList<Student> students = new ArrayList<Student>();
        // 存储所有学生对象

        // 注意集合的定义 尽量把泛型写全 防止安全检查

        for (int i = 0; i < countOfSubject; i++) {
            subjectNames[i] = in.next();
            map.put(subjectNames[i],i);
            // map 存储学科名字 对应 索引
        }

        for (int i = 0; i < countOfStudent; i++) {
            // 存储每个学生对象
            String studentName = in.next();
            int rank[] = new int[countOfSubject];
            for (int j = 0; j < countOfSubject; j++) {
                rank[j] = in.nextInt();
            }
            Student student = new Student(studentName,rank);
            students.add(student);
        }

        String temp = in.nextLine();
        // 吃回车
        String subjectSort = in.nextLine();
        // 存储 指示排序的学科名字 
        /*System.out.println(subjectSort);
        for(Student student:students){
            System.out.print(student.name + " ");
            for(int i=0;i<student.rank.length;i++){
                System.out.print(student.rank[i] + " ");
            }
            System.out.println();
        }*/
        if(map.get(subjectSort)!=null){
            // 这个学科名字 存在于 map中 取出对应的索引  这个索引一定能满足rank数组的上下界
            int index = map.get(subjectSort);
            // 执行排序  将students的ArrayList链表进行排序洗牌
            sortStudents(students, index);
        }
        else{
            int index = countOfSubject;
            // 这个学科名字 不存在  则 将索引设置为  学科数量 == rank最大索引 + 1
            // 此时index  对 rank 是越界的  这个将作为判断条件在排序函数中应用
            sortStudents(students,index);
        }
        for(Student student:students){
            // 排序结束 输出排序后的结果
            System.out.print(student.name + " ");
        }
    }

    public static void sortStudents(ArrayList<Student> students, int index){
        // 排序函数  重点!!!!!
        students.sort(new Comparator<Student>(){
            // new Comparator 对象
            // 覆写 compare 方法
            @Override
            public int compare(Student s1,Student s2){
                if(index>=0 && index<s1.rank.length && index<s2.rank.length){
                    // index 没有超过 rank 的正常上下索引 
                    int diff = s2.rank[index] - s1.rank[index];
                    if(diff!=0){
                        // 用来排序的值不同
                        return diff;
                    }
                    else{
                        // 用来排序的值相同的情况  用name的字典序列排序
                        return s1.name.compareTo(s2.name);
                    }
                }
                else{
                    // index 超出索引范围  用rank总和排序
                    int divSum = sumArray(s2.rank)-sumArray(s1.rank);
                    if(divSum != 0){
                        return divSum;
                    }
                    else{
                        // 用来排序的值相同的情况  用name的字典序列排序
                        return s1.name.compareTo(s2.name);
                    }
                }
            }
        });
    }

    public static int sumArray(int []rank){
        // 计算rank数组和
        int sum = 0;
        for(int value:rank){
            sum+=value;
        }
        return sum;
    }
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值